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