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