Seq.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.8.0).
003  * Copyright (c) 2007-2017 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics.util;
021 
022 import static java.util.Objects.requireNonNull;
023 import static java.util.stream.Collectors.joining;
024 
025 import java.util.ArrayList;
026 import java.util.Comparator;
027 import java.util.Iterator;
028 import java.util.List;
029 import java.util.ListIterator;
030 import java.util.Objects;
031 import java.util.RandomAccess;
032 import java.util.Spliterator;
033 import java.util.function.Function;
034 import java.util.function.Predicate;
035 import java.util.function.Supplier;
036 import java.util.stream.Collector;
037 import java.util.stream.Stream;
038 import java.util.stream.StreamSupport;
039 
040 /**
041  * General interface for a ordered, fixed sized, object sequence.
042  <br>
043  * Use the {@link #asList()} method to work together with the
044  * <a href="http://download.oracle.com/javase/6/docs/technotes/guides/collections/index.html">
045  * Java Collection Framework</a>.
046  *
047  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
048  @since 1.0
049  @version 3.4
050  */
051 public interface Seq<T> extends Iterable<T> {
052 
053     /**
054      * Return the value at the given {@code index}.
055      *
056      @param index index of the element to return.
057      @return the value at the given {@code index}.
058      @throws IndexOutOfBoundsException if the index is out of range
059      *         (index &lt; 0 || index &gt;= size()).
060      */
061     public T get(final int index);
062 
063     /**
064      * Return the length of this sequence. Once the sequence is created, the
065      * length can't be changed.
066      *
067      @return the length of this sequence.
068      */
069     public int length();
070 
071     /**
072      @see #length()
073      @return the size of this sequence
074      */
075     public default int size() {
076         return length();
077     }
078 
079     /**
080      * Returns {@code true} if this sequence contains no elements.
081      *
082      @since 3.3
083      *
084      @return {@code true} if this sequence contains no elements
085      */
086     public default boolean isEmpty() {
087         return length() == 0;
088     }
089 
090     /**
091      * Tests whether a predicate holds for all elements of this sequence.
092      *
093      @param predicate the predicate to use to test the elements.
094      @return {@code true} if the given predicate p holds for all elements of
095      *         this sequence, {@code false} otherwise.
096      @throws NullPointerException if the given {@code predicate} is
097      *         {@code null}.
098      */
099     public default boolean forAll(final Predicate<? super T> predicate) {
100         boolean valid = true;
101 
102         if (this instanceof RandomAccess) {
103             for (int i = 0, n = length(); i < n && valid; ++i) {
104                 valid = predicate.test(get(i));
105             }
106         else {
107             final Iterator<T> it = iterator();
108             while (it.hasNext() && valid) {
109                 valid = predicate.test(it.next());
110             }
111         }
112 
113         return valid;
114     }
115 
116     public default Iterator<T> iterator() {
117         return asList().iterator();
118     }
119 
120     public default ListIterator<T> listIterator() {
121         return asList().listIterator();
122     }
123 
124     /**
125      * Returns a sequential Stream with this sequence as its source.
126      *
127      @since 3.0
128      *
129      @return a sequential Stream over the elements in this sequence
130      */
131     public default Stream<T> stream() {
132         return StreamSupport.stream(new SeqSpliterator<>(this)false);
133     }
134 
135     /**
136      * Returns a possibly parallel {@code Stream} with this sequence as its
137      * source.  It is allowable for this method to return a sequential stream.
138      *
139      @since 3.0
140      *
141      @return a possibly parallel {@code Stream} over the elements in this
142      * collection
143      */
144     public default Stream<T> parallelStream() {
145         return StreamSupport.stream(new SeqSpliterator<>(this)true);
146     }
147 
148     @Override
149     public default Spliterator<T> spliterator() {
150         return new SeqSpliterator<T>(this);
151     }
152 
153     /**
154      * Returns {@code true} if this sequence contains the specified element.
155      *
156      @param element element whose presence in this sequence is to be tested.
157      *        The tested element can be {@code null}.
158      @return {@code true} if this sequence contains the specified element
159      */
160     public default boolean contains(final Object element) {
161         return indexOf(element!= -1;
162     }
163 
164     /**
165      * Returns the index of the first occurrence of the specified element
166      * in this sequence, or -1 if this sequence does not contain the element.
167      *
168      @param element element to search for, can be {@code null}
169      @return the index of the first occurrence of the specified element in
170      *          this sequence, or -1 if this sequence does not contain the element
171      */
172     public default int indexOf(final Object element) {
173         return indexOf(element, 0, length());
174     }
175 
176     /**
177      * Returns the index of the first occurrence of the specified element
178      * in this sequence, or -1 if this sequence does not contain the element.
179      *
180      @param element element to search for, can be {@code null}
181      @param start the start index (inclusively) for the element search.
182      @return the index of the first occurrence of the specified element in
183      *          this sequence, or -1 if this sequence does not contain the element
184      @throws IndexOutOfBoundsException for an illegal end point index value
185      *          ({@code start < 0 || start > length()}).
186      */
187     public default int indexOf(final Object element, final int start) {
188         return indexOf(element, start, length());
189     }
190 
191     /**
192      * Returns the index of the first occurrence of the specified element
193      * in this sequence, or -1 if this sequence does not contain the element.
194      *
195      @param element element to search for, can be {@code null}
196      @param start the start index (inclusively) for the element search.
197      @param end the end index (exclusively) for the element search.
198      @return the index of the first occurrence of the specified element in
199      *          this sequence, or -1 if this sequence does not contain the element
200      @throws IndexOutOfBoundsException for an illegal end point index value
201      *          ({@code start < 0 || end > length() || start > end}).
202      */
203     public default int indexOf(final Object element, final int start, final int end) {
204         return element != null
205             ? indexWhere(element::equals, start, end)
206             : indexWhere(Objects::isNull, start, end);
207     }
208 
209     /**
210      <p>
211      * Returns the index of the first element on which the given predicate
212      * returns {@code true}, or -1 if the predicate returns false for every
213      * sequence element.
214      </p>
215      <pre>{@code
216      * // Finding index of first null value.
217      * final int index = seq.indexOf(o -> o == null);
218      *
219      * // Assert of no null values.
220      * assert (sequence.indexOf(o -> o == null) == -1);
221      * }</pre>
222      *
223      @param predicate the search predicate.
224      @return the index of the first element on which the given predicate
225      *          returns {@code true}, or -1 if the predicate returns {@code false}
226      *          for every sequence element.
227      @throws NullPointerException if the given {@code predicate} is {@code null}.
228      */
229     public default int indexWhere(final Predicate<? super T> predicate) {
230         return indexWhere(predicate, 0, length());
231     }
232 
233     /**
234      <p>
235      * Returns the index of the first element on which the given predicate
236      * returns {@code true}, or -1 if the predicate returns false for every
237      * sequence element.
238      </p>
239      <pre>{@code
240      * // Finding index of first null value.
241      * final int index = seq.indexOf(o -> o == null);
242      *
243      * // Assert of no null values.
244      * assert (sequence.indexOf(o -> o == null) == -1);
245      * }</pre>
246      *
247      @param predicate the search predicate.
248      @param start the search start index
249      @return the index of the first element on which the given predicate
250      *          returns {@code true}, or -1 if the predicate returns {@code false}
251      *          for every sequence element.
252      @throws NullPointerException if the given {@code predicate} is {@code null}.
253      @throws IndexOutOfBoundsException for an illegal end point index value
254      *          ({@code start < 0 || start > length()}).
255      */
256     public default int indexWhere(
257         final Predicate<? super T> predicate,
258         final int start
259     ) {
260         return indexWhere(predicate, start, length());
261     }
262 
263     /**
264      <p>
265      * Returns the index of the first element on which the given predicate
266      * returns {@code true}, or -1 if the predicate returns false for every
267      * sequence element.
268      </p>
269      <pre>{@code
270      * // Finding index of first null value.
271      * final int index = seq.indexOf(o -> o == null);
272      *
273      * // Assert of no null values.
274      * assert (sequence.indexOf(o -> o == null) == -1);
275      * }</pre>
276      *
277      @param predicate the search predicate.
278      @param start the search start index
279      @param end the search end index
280      @return the index of the first element on which the given predicate
281      *          returns {@code true}, or -1 if the predicate returns {@code false}
282      *          for every sequence element.
283      @throws NullPointerException if the given {@code predicate} is {@code null}.
284      @throws IndexOutOfBoundsException for an illegal end point index value
285      *          ({@code start < 0 || end > length() || start > end}).
286      */
287     public default int indexWhere(
288         final Predicate<? super T> predicate,
289         final int start,
290         final int end
291     ) {
292         requireNonNull(predicate, "Predicate");
293 
294         int index = -1;
295         for (int i = 0, n = length(); i < n && index == -1; ++i) {
296             if (predicate.test(get(i))) {
297                 index = i;
298             }
299         }
300         return index;
301     }
302 
303     /**
304      * Returns the index of the last occurrence of the specified element
305      * in this sequence, or -1 if this sequence does not contain the element.
306      *
307      @param element element to search for, can be {@code null}
308      @return the index of the last occurrence of the specified element in
309      *         this sequence, or -1 if this sequence does not contain the element
310      */
311     public default int lastIndexOf(final Object element) {
312         return lastIndexOf(element, 0, length());
313     }
314 
315     /**
316      * Returns the index of the last occurrence of the specified element
317      * in this sequence, or -1 if this sequence does not contain the element.
318      *
319      @param element element to search for, can be {@code null}
320      @param end the search end index
321      @return the index of the last occurrence of the specified element in
322      *         this sequence, or -1 if this sequence does not contain the element
323      @throws IndexOutOfBoundsException for an illegal end point index value
324      *          ({@code end < 0 || end > length()}).
325      */
326     public default int lastIndexOf(final Object element, final int end) {
327         return lastIndexOf(element, 0, end);
328     }
329 
330     /**
331      * Returns the index of the last occurrence of the specified element
332      * in this sequence, or -1 if this sequence does not contain the element.
333      *
334      @param element element to search for, can be {@code null}
335      @param start the search start index
336      @param end the search end index
337      @return the index of the last occurrence of the specified element in
338      *         this sequence, or -1 if this sequence does not contain the element
339      @throws IndexOutOfBoundsException for an illegal end point index value
340      *          ({@code start < 0 || end > length() || start > end}).
341      */
342     public default int lastIndexOf(
343         final Object element,
344         final int start,
345         final int end
346     ) {
347         return element != null ?
348             lastIndexWhere(element::equals, start, end:
349             lastIndexWhere(Objects::isNull, start, end);
350     }
351 
352     /**
353      * Returns the index of the last element on which the given predicate
354      * returns {@code true}, or -1 if the predicate returns false for every
355      * sequence element.
356      *
357      @param predicate the search predicate.
358      @return the index of the last element on which the given predicate
359      *          returns {@code true}, or -1 if the predicate returns false for
360      *          every sequence element.
361      @throws NullPointerException if the given {@code predicate} is {@code null}.
362      */
363     public default int lastIndexWhere(final Predicate<? super T> predicate) {
364         return lastIndexWhere(predicate, 0, length());
365     }
366 
367     /**
368      * Returns the index of the last element on which the given predicate
369      * returns {@code true}, or -1 if the predicate returns false for every
370      * sequence element.
371      *
372      @param predicate the search predicate.
373      @param end the search end index
374      @return the index of the last element on which the given predicate
375      *          returns {@code true}, or -1 if the predicate returns false for
376      *          every sequence element.
377      @throws NullPointerException if the given {@code predicate} is {@code null}.
378      @throws IndexOutOfBoundsException for an illegal end point index value
379      *          ({@code end < 0 || end > length()}).
380      */
381     public default int lastIndexWhere(
382         final Predicate<? super T> predicate,
383         final int end
384     ) {
385         return lastIndexWhere(predicate, 0, end);
386     }
387 
388     /**
389      * Returns the index of the last element on which the given predicate
390      * returns {@code true}, or -1 if the predicate returns false for every
391      * sequence element.
392      *
393      @param predicate the search predicate.
394      @param start the search start index
395      @param end the search end index
396      @return the index of the last element on which the given predicate
397      *          returns {@code true}, or -1 if the predicate returns false for
398      *          every sequence element.
399      @throws NullPointerException if the given {@code predicate} is {@code null}.
400      @throws IndexOutOfBoundsException for an illegal end point index value
401      *          ({@code start < 0 || end > length() || start > end}).
402      */
403     public default int lastIndexWhere(
404         final Predicate<? super T> predicate,
405         final int start,
406         final int end
407     ) {
408         requireNonNull(predicate, "Predicate");
409 
410         int index = -1;
411         for (int i = length(); --i >= && index == -1;) {
412             if (predicate.test(get(i))) {
413                 index = i;
414             }
415         }
416         return index;
417     }
418 
419     /**
420      * Builds a new sequence by applying a function to all elements of this
421      * sequence.
422      *
423      @param <B> the element type of the returned collection.
424      @param mapper the function to apply to each element.
425      @return a new sequence of type That resulting from applying the given
426      *         function f to each element of this sequence and collecting the
427      *         results.
428      @throws NullPointerException if the element {@code mapper} is
429      *         {@code null}.
430      */
431     public <B> Seq<B> map(final Function<? super T, ? extends B> mapper);
432 
433     /**
434      * Return a <i>new</i> {@code Seq} with the given {@code values} appended.
435      *
436      @since 3.4
437      *
438      @param values the values to append
439      @return <i>new</i> {@code Seq} with the elements of {@code this}
440      *        sequence and the given {@code values} appended.
441      @throws NullPointerException if the given {@code values} array is
442      *         {@code null}
443      */
444     @SuppressWarnings("unchecked")
445     public default Seq<T> append(final T... values) {
446         return append(Seq.of(values));
447     }
448 
449     /**
450      * Return a <i>new</i> {@code Seq} with the given {@code values} appended.
451      *
452      @since 3.4
453      *
454      @param values the values to append
455      @return <i>new</i> {@code Seq} with the elements of {@code this}
456      *        sequence and the given {@code values} appended.
457      @throws NullPointerException if the given {@code values} iterable is
458      *         {@code null}
459      */
460     public Seq<T> append(final Iterable<? extends T> values);
461 
462     /**
463      * Return a <i>new</i> {@code Seq} with the given {@code values} prepended.
464      *
465      @since 3.4
466      *
467      @param values the values to append
468      @return <i>new</i> {@code Seq} with the elements of {@code this}
469      *        sequence and the given {@code values} prepended.
470      @throws NullPointerException if the given {@code values} array is
471      *         {@code null}
472      */
473     @SuppressWarnings("unchecked")
474     public default Seq<T> prepend(final T... values) {
475         return prepend(Seq.of(values));
476     }
477 
478     /**
479      * Return a <i>new</i> {@code Seq} with the given {@code values} prepended.
480      *
481      @since 3.4
482      *
483      @param values the values to append
484      @return <i>new</i> {@code Seq} with the elements of {@code this}
485      *        sequence and the given {@code values} prepended.
486      @throws NullPointerException if the given {@code values} array is
487      *         {@code null}
488      */
489     public Seq<T> prepend(final Iterable<? extends T> values);
490 
491     /**
492      * Returns a fixed-size list backed by the specified sequence. (Changes to
493      * the returned list "write through" to the array.) The returned list is
494      * fixed size, serializable and implements {@link RandomAccess}.
495      *
496      @return a list view of this sequence
497      */
498     public default List<T> asList() {
499         return new SeqList<>(this);
500     }
501 
502     /**
503      * Return an array containing all of the elements in this sequence in right
504      * order. The returned array will be "safe" in that no references to it
505      * are maintained by this sequence. (In other words, this method must allocate
506      * a new array.) The caller is thus free to modify the returned array.
507      *
508      @see java.util.Collection#toArray()
509      *
510      @return an array containing all of the elements in this list in right
511      *          order
512      */
513     public default Object[] toArray() {
514         final Object[] array = new Object[size()];
515         for (int i = size(); --i >= 0;) {
516             array[i= get(i);
517         }
518         return array;
519     }
520 
521     /**
522      * Return an array containing all of the elements in this sequence in right
523      * order; the runtime type of the returned array is that of the specified
524      * array. If this sequence fits in the specified array, it is returned
525      * therein. Otherwise, a new array is allocated with the runtime type of the
526      * specified array and the length of this array.
527      <p>
528      * If this sequence fits in the specified array with room to spare (i.e.,
529      * the array has more elements than this array), the element in the array
530      * immediately following the end of this array is set to null. (This is
531      * useful in determining the length of the array only if the caller knows
532      * that the list does not contain any null elements.)
533      *
534      @see java.util.Collection#toArray(Object[])
535      *
536      @param array the array into which the elements of this array are to be
537      *         stored, if it is big enough; otherwise, a new array of the same
538      *         runtime type is allocated for this purpose.
539      @return an array containing the elements of this array
540      @throws ArrayStoreException if the runtime type of the specified array is
541      *         not a super type of the runtime type of every element in this
542      *         array
543      @throws NullPointerException if the given array is {@code null}.
544      */
545     @SuppressWarnings("unchecked")
546     public default T[] toArray(final T[] array) {
547         if (array.length < length()) {
548             final T[] copy = (T[])java.lang.reflect.Array.newInstance(
549                 array.getClass().getComponentType(), length()
550             );
551             for (int i = length(); --i >= 0;) {
552                 copy[i= get(i);
553             }
554 
555             return copy;
556         }
557 
558         for (int i = 0, n = length(); i < n; ++i) {
559             array[i= get(i);
560         }
561         return array;
562     }
563 
564     /**
565      * Returns a view of the portion of this sequence between the specified
566      * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
567      * and {@code end} are equal, the returned sequence has the length zero.)
568      * The returned sequence is backed by this sequence, so non-structural
569      * changes in the returned sequence are reflected in this sequence, and
570      * vice-versa.
571      <p>
572      * This method eliminates the need for explicit range operations (of the
573      * populationSort that commonly exist for arrays). Any operation that
574      * expects an sequence can be used as a range operation by passing an sub
575      * sequence view instead of an whole sequence.
576      *
577      @param start low end point (inclusive) of the sub array.
578      @return a view of the specified range within this array.
579      @throws IndexOutOfBoundsException for an illegal end point index value
580      *          ({@code start < 0 || start > length()}).
581      */
582     public Seq<T> subSeq(final int start);
583 
584     /**
585      * Returns a view of the portion of this sequence between the specified
586      * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
587      * and {@code end} are equal, the returned sequence has the length zero.)
588      * The returned sequence is backed by this sequence, so non-structural
589      * changes in the returned sequence are reflected in this array, and
590      * vice-versa.
591      <p>
592      * This method eliminates the need for explicit range operations (of the
593      * populationSort that commonly exist for arrays). Any operation that
594      * expects an array can be used as a range operation by passing an sub
595      * sequence view instead of an whole sequence.
596      *
597      @param start low end point (inclusive) of the sub sequence.
598      @param end high end point (exclusive) of the sub sequence.
599      @return a view of the specified range within this sequence.
600      @throws IndexOutOfBoundsException for an illegal end point index value
601      *          ({@code start < 0 || end > length() || start > end}).
602      */
603     public Seq<T> subSeq(final int start, final int end);
604 
605     /**
606      * Test whether the given array is sorted in ascending order.
607      *
608      @return {@code true} if the given {@code array} is sorted in ascending
609      *         order, {@code false} otherwise.
610      @throws NullPointerException if the given array or one of it's element is
611      *         {@code null}.
612      */
613     @SuppressWarnings("unchecked")
614     public default boolean isSorted() {
615         boolean sorted = true;
616         for (int i = 0, n = length() 1; i < n && sorted; ++i) {
617             sorted = ((Comparable<T>)get(i)).compareTo(get(i + 1)) <= 0;
618         }
619 
620         return sorted;
621     }
622 
623     /**
624      * Test whether the given array is sorted in ascending order. The order of
625      * the array elements is defined by the given comparator.
626      *
627      @param comparator the comparator which defines the order.
628      @return {@code true} if the given {@code array} is sorted in ascending
629      *         order, {@code false} otherwise.
630      @throws NullPointerException if the given array or one of it's element or
631      *         the comparator is {@code null}.
632      */
633     public default boolean isSorted(final Comparator<? super T> comparator) {
634         boolean sorted = true;
635         for (int i = 0, n = length() 1; i < n && sorted; ++i) {
636             sorted = comparator.compare(get(i), get(i + 1)) <= 0;
637         }
638 
639         return sorted;
640     }
641 
642     /**
643      * Return this sequence as {@code MSeq} instance. If {@code this} is not a
644      * {@code MSeq} a new seq is created.
645      *
646      @since 3.8
647      *
648      @return a {@code MSeq} with this values
649      */
650     public default MSeq<T> asMSeq() {
651         return this instanceof MSeq<?> ? (MSeq<T>)this : MSeq.of(this);
652     }
653 
654     /**
655      * Return this sequence as {@code ISeq} instance. If {@code this} is not a
656      * {@code ISeq} a new seq is created.
657      *
658      @since 3.8
659      *
660      @return a {@code ISeq} with this values
661      */
662     public default ISeq<T> asISeq() {
663         return this instanceof ISeq<?> ? (ISeq<T>)this : ISeq.of(this);
664     }
665 
666     /**
667      * Returns the hash code value for this sequence. The hash code is defined
668      * as followed:
669      *
670      <pre>{@code
671      * int hashCode = 1;
672      * final Iterator<E> it = seq.iterator();
673      * while (it.hasNext()) {
674      *     final E obj = it.next();
675      *     hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
676      * }
677      * }</pre>
678      *
679      @see List#hashCode()
680      @see Seq#hashCode(Seq)
681      *
682      @return the hash code value for this list
683      */
684     @Override
685     public int hashCode();
686 
687     /**
688      * Compares the specified object with this sequence for equality. Returns
689      * true if and only if the specified object is also a sequence, both
690      * sequence have the same size, and all corresponding pairs of elements in
691      * the two sequences are equal. (Two elements e1 and e2 are equal if
692      * (e1==null ? e2==null : e1.equals(e2)).) This definition ensures that the
693      * equals method works properly across different implementations of the Seq
694      * interface.
695      *
696      @see List#equals(Object)
697      @see Seq#equals(Seq, Object)
698      *
699      @param object the object to be compared for equality with this sequence.
700      @return {@code true} if the specified object is equal to this sequence,
701      *          {@code false} otherwise.
702      */
703     @Override
704     public boolean equals(final Object object);
705 
706     /**
707      * Create a string representation of the given sequence.
708      *
709      @param prefix the prefix of the string representation; e.g {@code '['}.
710      @param separator the separator of the array elements; e.g. {@code ','}.
711      @param suffix the suffix of the string representation; e.g. {@code ']'}.
712      @return the string representation of this sequence.
713      */
714     public default String toString(
715         final String prefix,
716         final String separator,
717         final String suffix
718     ) {
719         return stream()
720             .map(Objects::toString)
721             .collect(joining(separator, prefix, suffix));
722     }
723 
724     /**
725      * Create a string representation of the given sequence.
726      *
727      @param separator the separator of the array elements; e.g. {@code ','}.
728      @return the string representation of this sequence.
729      */
730     public default String toString(final String separator) {
731         return toString("", separator, "");
732     }
733 
734     /**
735      * Unified method for calculating the hash code of every {@link Seq}
736      * implementation. The hash code is defined as followed:
737      *
738      <pre>{@code
739      * int hashCode = 1;
740      * final Iterator<E> it = seq.iterator();
741      * while (it.hasNext()) {
742      *     final E obj = it.next();
743      *     hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
744      * }
745      * }</pre>
746      *
747      @see Seq#hashCode()
748      @see List#hashCode()
749      *
750      @param seq the sequence to calculate the hash code for.
751      @return the hash code of the given sequence.
752      */
753     public static int hashCode(final Seq<?> seq) {
754         int hash = 1;
755         for (Object element : seq) {
756             hash = 31*hash + (element == null 0: element.hashCode());
757         }
758         return hash;
759     }
760 
761     /**
762      * Unified method for compare to sequences for equality.
763      *
764      @see Seq#equals(Object)
765      *
766      @param seq the sequence to test for equality.
767      @param obj the object to test for equality with the sequence.
768      @return {@code true} if the given objects are sequences and contain the
769      *          same objects in the same order, {@code false} otherwise.
770      */
771     public static boolean equals(final Seq<?> seq, final Object obj) {
772         if (obj == seq) {
773             return true;
774         }
775         if (!(obj instanceof Seq<?>)) {
776             return false;
777         }
778 
779         final Seq<?> other = (Seq<?>)obj;
780         boolean equals = seq.length() == other.length();
781         for (int i = seq.length(); equals && --i >= 0;) {
782             final Object element = seq.get(i);
783             if (element != null) {
784                 equals = element.equals(other.get(i));
785             else {
786                 equals = other.get(i== null;
787             }
788         }
789         return equals;
790     }
791 
792     /* *************************************************************************
793      *  Some static factory methods.
794      * ************************************************************************/
795 
796     /**
797      * Single instance of an empty {@code Seq}.
798      *
799      @since 3.3
800      */
801     public static final Seq<?> EMPTY = ISeq.EMPTY;
802 
803     /**
804      * Return an empty {@code Seq}.
805      *
806      @since 3.3
807      *
808      @param <T> the element type of the returned {@code Seq}.
809      @return an empty {@code Seq}.
810      */
811     public static <T> Seq<T> empty() {
812         return ISeq.empty();
813     }
814 
815     /**
816      * Returns a {@code Collector} that accumulates the input elements into a
817      * new {@code Seq}.
818      *
819      @param <T> the type of the input elements
820      @return a {@code Collector} which collects all the input elements into a
821      *         {@code Seq}, in encounter order
822      */
823     public static <T> Collector<T, ?, Seq<T>> toSeq() {
824         return Collector.of(
825             (Supplier<List<T>>)ArrayList::new,
826             List::add,
827             (left, right-> left.addAll(right)return left; },
828             Seq::of
829         );
830     }
831 
832     /**
833      * Create a new {@code Seq} from the given values.
834      *
835      @param <T> the element type
836      @param values the array values.
837      @return a new {@code Seq} with the given values.
838      @throws NullPointerException if the {@code values} array is {@code null}.
839      */
840     @SafeVarargs
841     public static <T> Seq<T> of(final T... values) {
842         return ISeq.of(values);
843     }
844 
845     /**
846      * Create a new {@code Seq} from the given values.
847      *
848      @param <T> the element type
849      @param values the array values.
850      @return a new {@code Seq} with the given values.
851      @throws NullPointerException if the {@code values} array is {@code null}.
852      */
853     public static <T> Seq<T> of(final Iterable<? extends T> values) {
854         return ISeq.of(values);
855     }
856 
857 //    /**
858 //     * Create a new {@code Seq} instance from the remaining elements of the
859 //     * given iterator.
860 //     *
861 //     * @since 3.3
862 //     *
863 //     * @param <T> the element type.
864 //     * @return a new {@code Seq} with the given remaining values.
865 //     * @throws NullPointerException if the {@code values} object is
866 //     *        {@code null}.
867 //     */
868 //    public static <T> Seq<T> of(final Iterator<? extends T> values) {
869 //        final MSeq<T> seq = MSeq.of(values);
870 //        return seq.isEmpty() ? empty() : seq.toISeq();
871 //    }
872 
873     /**
874      * Creates a new sequence, which is filled with objects created be the given
875      * {@code supplier}.
876      *
877      @since 3.3
878      *
879      @param <T> the element type of the sequence
880      @param supplier the {@code Supplier} which creates the elements, the
881      *        returned sequence is filled with
882      @param length the length of the returned sequence
883      @return a new sequence filled with elements given by the {@code supplier}
884      @throws NegativeArraySizeException if the given {@code length} is
885      *         negative
886      @throws NullPointerException if the given {@code supplier} is
887      *         {@code null}
888      */
889     static <T> Seq<T> of(Supplier<? extends T> supplier, final int length) {
890         return ISeq.of(supplier, length);
891     }
892 
893 }