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