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 < 0 || index >= 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 a <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 a <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 a <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 a <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 }
|