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