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