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