Seq.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.7.0).
003  * Copyright (c) 2007-2016 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      * Returns the hash code value for this sequence. The hash code is defined
644      * as followed:
645      *
646      <pre>{@code
647      * int hashCode = 1;
648      * final Iterator<E> it = seq.iterator();
649      * while (it.hasNext()) {
650      *     final E obj = it.next();
651      *     hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
652      * }
653      * }</pre>
654      *
655      @see List#hashCode()
656      @see Seq#hashCode(Seq)
657      *
658      @return the hash code value for this list
659      */
660     @Override
661     public int hashCode();
662 
663     /**
664      * Compares the specified object with this sequence for equality. Returns
665      * true if and only if the specified object is also a sequence, both
666      * sequence have the same size, and all corresponding pairs of elements in
667      * the two sequences are equal. (Two elements e1 and e2 are equal if
668      * (e1==null ? e2==null : e1.equals(e2)).) This definition ensures that the
669      * equals method works properly across different implementations of the Seq
670      * interface.
671      *
672      @see List#equals(Object)
673      @see Seq#equals(Seq, Object)
674      *
675      @param object the object to be compared for equality with this sequence.
676      @return {@code true} if the specified object is equal to this sequence,
677      *          {@code false} otherwise.
678      */
679     @Override
680     public boolean equals(final Object object);
681 
682     /**
683      * Create a string representation of the given sequence.
684      *
685      @param prefix the prefix of the string representation; e.g {@code '['}.
686      @param separator the separator of the array elements; e.g. {@code ','}.
687      @param suffix the suffix of the string representation; e.g. {@code ']'}.
688      @return the string representation of this sequence.
689      */
690     public default String toString(
691         final String prefix,
692         final String separator,
693         final String suffix
694     ) {
695         return stream()
696             .map(Objects::toString)
697             .collect(joining(separator, prefix, suffix));
698     }
699 
700     /**
701      * Create a string representation of the given sequence.
702      *
703      @param separator the separator of the array elements; e.g. {@code ','}.
704      @return the string representation of this sequence.
705      */
706     public default String toString(final String separator) {
707         return toString("", separator, "");
708     }
709 
710     /**
711      * Unified method for calculating the hash code of every {@link Seq}
712      * implementation. The hash code is defined as followed:
713      *
714      <pre>{@code
715      * int hashCode = 1;
716      * final Iterator<E> it = seq.iterator();
717      * while (it.hasNext()) {
718      *     final E obj = it.next();
719      *     hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
720      * }
721      * }</pre>
722      *
723      @see Seq#hashCode()
724      @see List#hashCode()
725      *
726      @param seq the sequence to calculate the hash code for.
727      @return the hash code of the given sequence.
728      */
729     public static int hashCode(final Seq<?> seq) {
730         int hash = 1;
731         for (Object element : seq) {
732             hash = 31*hash + (element == null 0: element.hashCode());
733         }
734         return hash;
735     }
736 
737     /**
738      * Unified method for compare to sequences for equality.
739      *
740      @see Seq#equals(Object)
741      *
742      @param seq the sequence to test for equality.
743      @param obj the object to test for equality with the sequence.
744      @return {@code true} if the given objects are sequences and contain the
745      *          same objects in the same order, {@code false} otherwise.
746      */
747     public static boolean equals(final Seq<?> seq, final Object obj) {
748         if (obj == seq) {
749             return true;
750         }
751         if (!(obj instanceof Seq<?>)) {
752             return false;
753         }
754 
755         final Seq<?> other = (Seq<?>)obj;
756         boolean equals = seq.length() == other.length();
757         for (int i = seq.length(); equals && --i >= 0;) {
758             final Object element = seq.get(i);
759             if (element != null) {
760                 equals = element.equals(other.get(i));
761             else {
762                 equals = other.get(i== null;
763             }
764         }
765         return equals;
766     }
767 
768     /* *************************************************************************
769      *  Some static factory methods.
770      * ************************************************************************/
771 
772     /**
773      * Single instance of an empty {@code Seq}.
774      *
775      @since 3.3
776      */
777     public static final Seq<?> EMPTY = ISeq.EMPTY;
778 
779     /**
780      * Return an empty {@code Seq}.
781      *
782      @since 3.3
783      *
784      @param <T> the element type of the returned {@code Seq}.
785      @return an empty {@code Seq}.
786      */
787     public static <T> Seq<T> empty() {
788         return ISeq.empty();
789     }
790 
791     /**
792      * Returns a {@code Collector} that accumulates the input elements into a
793      * new {@code Seq}.
794      *
795      @param <T> the type of the input elements
796      @return a {@code Collector} which collects all the input elements into a
797      *         {@code Seq}, in encounter order
798      */
799     public static <T> Collector<T, ?, Seq<T>> toSeq() {
800         return Collector.of(
801             (Supplier<List<T>>)ArrayList::new,
802             List::add,
803             (left, right-> left.addAll(right)return left; },
804             Seq::of
805         );
806     }
807 
808     /**
809      * Create a new {@code Seq} from the given values.
810      *
811      @param <T> the element type
812      @param values the array values.
813      @return a new {@code Seq} with the given values.
814      @throws NullPointerException if the {@code values} array is {@code null}.
815      */
816     @SafeVarargs
817     public static <T> Seq<T> of(final T... values) {
818         return ISeq.of(values);
819     }
820 
821     /**
822      * Create a new {@code Seq} from the given values.
823      *
824      @param <T> the element type
825      @param values the array values.
826      @return a new {@code Seq} with the given values.
827      @throws NullPointerException if the {@code values} array is {@code null}.
828      */
829     public static <T> Seq<T> of(final Iterable<? extends T> values) {
830         return ISeq.of(values);
831     }
832 
833 //    /**
834 //     * Create a new {@code Seq} instance from the remaining elements of the
835 //     * given iterator.
836 //     *
837 //     * @since 3.3
838 //     *
839 //     * @param <T> the element type.
840 //     * @return a new {@code Seq} with the given remaining values.
841 //     * @throws NullPointerException if the {@code values} object is
842 //     *        {@code null}.
843 //     */
844 //    public static <T> Seq<T> of(final Iterator<? extends T> values) {
845 //        final MSeq<T> seq = MSeq.of(values);
846 //        return seq.isEmpty() ? empty() : seq.toISeq();
847 //    }
848 
849     /**
850      * Creates a new sequence, which is filled with objects created be the given
851      * {@code supplier}.
852      *
853      @since 3.3
854      *
855      @param <T> the element type of the sequence
856      @param supplier the {@code Supplier} which creates the elements, the
857      *        returned sequence is filled with
858      @param length the length of the returned sequence
859      @return a new sequence filled with elements given by the {@code supplier}
860      @throws NegativeArraySizeException if the given {@code length} is
861      *         negative
862      @throws NullPointerException if the given {@code supplier} is
863      *         {@code null}
864      */
865     static <T> Seq<T> of(Supplier<? extends T> supplier, final int length) {
866         return ISeq.of(supplier, length);
867     }
868 
869 }