001 /*
002 * Java Genetic Algorithm Library (jenetics-4.2.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 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 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 a view of the portion of this sequence between the specified
607 * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
608 * and {@code end} are equal, the returned sequence has the length zero.)
609 * The returned sequence is backed by this sequence, so non-structural
610 * changes in the returned sequence are reflected in this sequence, and
611 * vice-versa.
612 * <p>
613 * This method eliminates the need for explicit range operations (of the
614 * populationSort that commonly exist for arrays). Any operation that
615 * expects an sequence can be used as a range operation by passing an sub
616 * sequence view instead of an whole sequence.
617 *
618 * @param start low end point (inclusive) of the sub array.
619 * @return a view of the specified range within this array.
620 * @throws IndexOutOfBoundsException for an illegal end point index value
621 * ({@code start < 0 || start > length()}).
622 */
623 public Seq<T> subSeq(final int start);
624
625 /**
626 * Returns a view of the portion of this sequence between the specified
627 * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
628 * and {@code end} are equal, the returned sequence has the length zero.)
629 * The returned sequence is backed by this sequence, so non-structural
630 * changes in the returned sequence are reflected in this array, and
631 * vice-versa.
632 * <p>
633 * This method eliminates the need for explicit range operations (of the
634 * populationSort that commonly exist for arrays). Any operation that
635 * expects an array can be used as a range operation by passing an sub
636 * sequence view instead of an whole sequence.
637 *
638 * @param start low end point (inclusive) of the sub sequence.
639 * @param end high end point (exclusive) of the sub sequence.
640 * @return a view of the specified range within this sequence.
641 * @throws IndexOutOfBoundsException for an illegal end point index value
642 * ({@code start < 0 || end > length() || start > end}).
643 */
644 public Seq<T> subSeq(final int start, final int end);
645
646 /**
647 * Test whether the given array is sorted in ascending order.
648 *
649 * @return {@code true} if the given {@code array} is sorted in ascending
650 * order, {@code false} otherwise.
651 * @throws NullPointerException if the given array or one of it's element is
652 * {@code null}.
653 */
654 @SuppressWarnings("unchecked")
655 public default boolean isSorted() {
656 boolean sorted = true;
657 for (int i = 0, n = length() - 1; i < n && sorted; ++i) {
658 sorted = ((Comparable<T>)get(i)).compareTo(get(i + 1)) <= 0;
659 }
660
661 return sorted;
662 }
663
664 /**
665 * Test whether the given array is sorted in ascending order. The order of
666 * the array elements is defined by the given comparator.
667 *
668 * @param comparator the comparator which defines the order.
669 * @return {@code true} if the given {@code array} is sorted in ascending
670 * order, {@code false} otherwise.
671 * @throws NullPointerException if the given array or one of it's element or
672 * the comparator is {@code null}.
673 */
674 public default boolean isSorted(final Comparator<? super T> comparator) {
675 boolean sorted = true;
676 for (int i = 0, n = length() - 1; i < n && sorted; ++i) {
677 sorted = comparator.compare(get(i), get(i + 1)) <= 0;
678 }
679
680 return sorted;
681 }
682
683 /**
684 * Return this sequence as {@code MSeq} instance. If {@code this} is not a
685 * {@code MSeq} a new seq is created.
686 *
687 * @since 3.8
688 *
689 * @return a {@code MSeq} with this values
690 */
691 public default MSeq<T> asMSeq() {
692 return this instanceof MSeq ? (MSeq<T>)this : MSeq.of(this);
693 }
694
695 /**
696 * Return this sequence as {@code ISeq} instance. If {@code this} is not a
697 * {@code ISeq} a new seq is created.
698 *
699 * @since 3.8
700 *
701 * @return a {@code ISeq} with this values
702 */
703 public default ISeq<T> asISeq() {
704 return this instanceof ISeq ? (ISeq<T>)this : ISeq.of(this);
705 }
706
707 /**
708 * Returns the hash code value for this sequence. The hash code is defined
709 * as followed:
710 *
711 * <pre>{@code
712 * int hashCode = 1;
713 * final Iterator<E> it = seq.iterator();
714 * while (it.hasNext()) {
715 * final E obj = it.next();
716 * hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
717 * }
718 * }</pre>
719 *
720 * @see List#hashCode()
721 * @see Seq#hashCode(Seq)
722 *
723 * @return the hash code value for this list
724 */
725 @Override
726 public int hashCode();
727
728 /**
729 * Compares the specified object with this sequence for equality. Returns
730 * true if and only if the specified object is also a sequence, both
731 * sequence have the same size, and all corresponding pairs of elements in
732 * the two sequences are equal. (Two elements e1 and e2 are equal if
733 * (e1==null ? e2==null : e1.equals(e2)).) This definition ensures that the
734 * equals method works properly across different implementations of the Seq
735 * interface.
736 *
737 * @see List#equals(Object)
738 * @see Seq#equals(Seq, Object)
739 *
740 * @param object the object to be compared for equality with this sequence.
741 * @return {@code true} if the specified object is equal to this sequence,
742 * {@code false} otherwise.
743 */
744 @Override
745 public boolean equals(final Object object);
746
747 /**
748 * Create a string representation of the given sequence.
749 *
750 * @param prefix the prefix of the string representation; e.g {@code '['}.
751 * @param separator the separator of the array elements; e.g. {@code ','}.
752 * @param suffix the suffix of the string representation; e.g. {@code ']'}.
753 * @return the string representation of this sequence.
754 */
755 public default String toString(
756 final String prefix,
757 final String separator,
758 final String suffix
759 ) {
760 return stream()
761 .map(Objects::toString)
762 .collect(joining(separator, prefix, suffix));
763 }
764
765 /**
766 * Create a string representation of the given sequence.
767 *
768 * @param separator the separator of the array elements; e.g. {@code ','}.
769 * @return the string representation of this sequence.
770 */
771 public default String toString(final String separator) {
772 return toString("", separator, "");
773 }
774
775 /**
776 * Unified method for calculating the hash code of every {@link Seq}
777 * implementation. The hash code is defined as followed:
778 *
779 * <pre>{@code
780 * int hashCode = 1;
781 * final Iterator<E> it = seq.iterator();
782 * while (it.hasNext()) {
783 * final E obj = it.next();
784 * hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
785 * }
786 * }</pre>
787 *
788 * @see Seq#hashCode()
789 * @see List#hashCode()
790 *
791 * @param seq the sequence to calculate the hash code for.
792 * @return the hash code of the given sequence.
793 */
794 public static int hashCode(final Seq<?> seq) {
795 int hash = 1;
796 for (Object element : seq) {
797 hash = 31*hash + (element == null ? 0: element.hashCode());
798 }
799 return hash;
800 }
801
802 /**
803 * Unified method for compare to sequences for equality.
804 *
805 * @see Seq#equals(Object)
806 *
807 * @param seq the sequence to test for equality.
808 * @param obj the object to test for equality with the sequence.
809 * @return {@code true} if the given objects are sequences and contain the
810 * same objects in the same order, {@code false} otherwise.
811 */
812 public static boolean equals(final Seq<?> seq, final Object obj) {
813 if (obj == seq) {
814 return true;
815 }
816 if (!(obj instanceof Seq)) {
817 return false;
818 }
819
820 final Seq<?> other = (Seq<?>)obj;
821 boolean equals = seq.length() == other.length();
822 for (int i = seq.length(); equals && --i >= 0;) {
823 final Object element = seq.get(i);
824 if (element != null) {
825 equals = element.equals(other.get(i));
826 } else {
827 equals = other.get(i) == null;
828 }
829 }
830 return equals;
831 }
832
833 /* *************************************************************************
834 * Some static factory methods.
835 * ************************************************************************/
836
837 /**
838 * Single instance of an empty {@code Seq}.
839 *
840 * @since 3.3
841 */
842 public static final Seq<?> EMPTY = ISeq.EMPTY;
843
844 /**
845 * Return an empty {@code Seq}.
846 *
847 * @since 3.3
848 *
849 * @param <T> the element type of the returned {@code Seq}.
850 * @return an empty {@code Seq}.
851 */
852 public static <T> Seq<T> empty() {
853 return ISeq.empty();
854 }
855
856 /**
857 * Returns a {@code Collector} that accumulates the input elements into a
858 * new {@code Seq}.
859 *
860 * @param <T> the type of the input elements
861 * @return a {@code Collector} which collects all the input elements into a
862 * {@code Seq}, in encounter order
863 */
864 public static <T> Collector<T, ?, Seq<T>> toSeq() {
865 return Collector.of(
866 (Supplier<List<T>>)ArrayList::new,
867 List::add,
868 (left, right) -> { left.addAll(right); return left; },
869 Seq::of
870 );
871 }
872
873 /**
874 * Create a new {@code Seq} from the given values.
875 *
876 * @param <T> the element type
877 * @param values the array values.
878 * @return a new {@code Seq} with the given values.
879 * @throws NullPointerException if the {@code values} array is {@code null}.
880 */
881 @SafeVarargs
882 public static <T> Seq<T> of(final T... values) {
883 return ISeq.of(values);
884 }
885
886 /**
887 * Create a new {@code Seq} from the given values.
888 *
889 * @param <T> the element type
890 * @param values the array values.
891 * @return a new {@code Seq} with the given values.
892 * @throws NullPointerException if the {@code values} array is {@code null}.
893 */
894 public static <T> Seq<T> of(final Iterable<? extends T> values) {
895 return ISeq.of(values);
896 }
897
898 // /**
899 // * Create a new {@code Seq} instance from the remaining elements of the
900 // * given iterator.
901 // *
902 // * @since 3.3
903 // *
904 // * @param <T> the element type.
905 // * @return a new {@code Seq} with the given remaining values.
906 // * @throws NullPointerException if the {@code values} object is
907 // * {@code null}.
908 // */
909 // public static <T> Seq<T> of(final Iterator<? extends T> values) {
910 // final MSeq<T> seq = MSeq.of(values);
911 // return seq.isEmpty() ? empty() : seq.toISeq();
912 // }
913
914 /**
915 * Creates a new sequence, which is filled with objects created be the given
916 * {@code supplier}.
917 *
918 * @since 3.3
919 *
920 * @param <T> the element type of the sequence
921 * @param supplier the {@code Supplier} which creates the elements, the
922 * returned sequence is filled with
923 * @param length the length of the returned sequence
924 * @return a new sequence filled with elements given by the {@code supplier}
925 * @throws NegativeArraySizeException if the given {@code length} is
926 * negative
927 * @throws NullPointerException if the given {@code supplier} is
928 * {@code null}
929 */
930 static <T> Seq<T> of(Supplier<? extends T> supplier, final int length) {
931 return ISeq.of(supplier, length);
932 }
933
934
935 /**
936 * Returns a sequence backed by the specified list. (Changes to the given
937 * list are "write through" to the returned sequence.) This method acts
938 * as bridge between collection-based and sequence-based APIs.
939 *
940 * @since 4.2
941 *
942 * @param list the list containing the elements
943 * @param <T> the element type
944 * @return a sequence view of the given {@code list}
945 * @throws NullPointerException if the given list is {@code null}
946 */
947 public static <T> Seq<T> viewOf(final List<? extends T> list) {
948 return list.isEmpty()
949 ? empty()
950 : new SeqView<>(list);
951 }
952
953 /**
954 * Returns a fixed-size sequence backed by the specified array. (Changes to
955 * the given array are "write through" to the returned sequence.) This
956 * method acts as bridge between array-based and sequence-based APIs.
957 *
958 * @since 4.2
959 *
960 * @param array the array containing the sequence elements
961 * @param <T> the element type
962 * @return a sequence view of the given {@code array}
963 * @throws NullPointerException if the given array is {@code null}
964 */
965 public static <T> Seq<T> viewOf(final T[] array) {
966 return array.length == 0
967 ? empty()
968 : new SeqView<>(Arrays.asList(array));
969 }
970
971 }
|