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