0001 /*
0002 * Java Genetic Algorithm Library (jenetics-5.1.0).
0003 * Copyright (c) 2007-2019 Franz Wilhelmstötter
0004 *
0005 * Licensed under the Apache License, Version 2.0 (the "License");
0006 * you may not use this file except in compliance with the License.
0007 * You may obtain a copy of the License at
0008 *
0009 * http://www.apache.org/licenses/LICENSE-2.0
0010 *
0011 * Unless required by applicable law or agreed to in writing, software
0012 * distributed under the License is distributed on an "AS IS" BASIS,
0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014 * See the License for the specific language governing permissions and
0015 * limitations under the License.
0016 *
0017 * Author:
0018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
0019 */
0020 package io.jenetics.util;
0021
0022 import static java.util.Objects.requireNonNull;
0023 import static java.util.stream.Collectors.joining;
0024 import static io.jenetics.internal.collection.Array.checkIndex;
0025
0026 import java.util.ArrayList;
0027 import java.util.Arrays;
0028 import java.util.Comparator;
0029 import java.util.Iterator;
0030 import java.util.List;
0031 import java.util.ListIterator;
0032 import java.util.Objects;
0033 import java.util.RandomAccess;
0034 import java.util.Spliterator;
0035 import java.util.function.Function;
0036 import java.util.function.IntFunction;
0037 import java.util.function.Predicate;
0038 import java.util.function.Supplier;
0039 import java.util.stream.Collector;
0040 import java.util.stream.Stream;
0041 import java.util.stream.StreamSupport;
0042
0043 /**
0044 * General interface for a ordered, fixed sized, object sequence.
0045 * <br>
0046 * Use the {@link #asList()} method to work together with the
0047 * <a href="http://download.oracle.com/javase/6/docs/technotes/guides/collections/index.html">
0048 * Java Collection Framework</a>.
0049 *
0050 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0051 * @since 1.0
0052 * @version 4.2
0053 */
0054 public interface Seq<T> extends Iterable<T>, IntFunction<T> {
0055
0056 /**
0057 * Return the value at the given {@code index}.
0058 *
0059 * @see #apply(int)
0060 *
0061 * @param index index of the element to return.
0062 * @return the value at the given {@code index}.
0063 * @throws IndexOutOfBoundsException if the index is out of range
0064 * (index < 0 || index >= size()).
0065 */
0066 public T get(final int index);
0067
0068 /**
0069 * Return the value at the given {@code index}.
0070 *
0071 * @since 3.9
0072 *
0073 * @see #get(int)
0074 *
0075 * @param index index of the element to return.
0076 * @return the value at the given {@code index}.
0077 * @throws IndexOutOfBoundsException if the index is out of range
0078 * {@code index < 0 || index >= size()}.
0079 */
0080 @Override
0081 public default T apply(final int index) {
0082 return get(index);
0083 }
0084
0085 /**
0086 * Return the length of this sequence. Once the sequence is created, the
0087 * length can't be changed.
0088 *
0089 * @return the length of this sequence.
0090 */
0091 public int length();
0092
0093 /**
0094 * @see #length()
0095 * @return the size of this sequence
0096 */
0097 public default int size() {
0098 return length();
0099 }
0100
0101 /**
0102 * Returns {@code true} if this sequence contains no elements.
0103 *
0104 * @since 3.3
0105 *
0106 * @return {@code true} if this sequence contains no elements
0107 */
0108 public default boolean isEmpty() {
0109 return length() == 0;
0110 }
0111
0112 /**
0113 * Returns {@code true} if this sequence contains at least one element.
0114 *
0115 * @since 4.0
0116 *
0117 * @return {@code true} if this sequence contains at least one element
0118 */
0119 public default boolean nonEmpty() {
0120 return !isEmpty();
0121 }
0122
0123 /**
0124 * Tests whether a predicate holds for all elements of this sequence.
0125 *
0126 * @param predicate the predicate to use to test the elements.
0127 * @return {@code true} if the given predicate p holds for all elements of
0128 * this sequence, {@code false} otherwise.
0129 * @throws NullPointerException if the given {@code predicate} is
0130 * {@code null}.
0131 */
0132 public default boolean forAll(final Predicate<? super T> predicate) {
0133 boolean valid = true;
0134
0135 if (this instanceof RandomAccess) {
0136 for (int i = 0, n = length(); i < n && valid; ++i) {
0137 valid = predicate.test(get(i));
0138 }
0139 } else {
0140 final Iterator<T> it = iterator();
0141 while (it.hasNext() && valid) {
0142 valid = predicate.test(it.next());
0143 }
0144 }
0145
0146 return valid;
0147 }
0148
0149 @Override
0150 public default Iterator<T> iterator() {
0151 return asList().iterator();
0152 }
0153
0154 public default ListIterator<T> listIterator() {
0155 return asList().listIterator();
0156 }
0157
0158 /**
0159 * Returns a sequential Stream with this sequence as its source.
0160 *
0161 * @since 3.0
0162 *
0163 * @return a sequential Stream over the elements in this sequence
0164 */
0165 public default Stream<T> stream() {
0166 return StreamSupport.stream(new SeqSpliterator<>(this), false);
0167 }
0168
0169 /**
0170 * Returns a possibly parallel {@code Stream} with this sequence as its
0171 * source. It is allowable for this method to return a sequential stream.
0172 *
0173 * @since 3.0
0174 *
0175 * @return a possibly parallel {@code Stream} over the elements in this
0176 * collection
0177 */
0178 public default Stream<T> parallelStream() {
0179 return StreamSupport.stream(new SeqSpliterator<>(this), true);
0180 }
0181
0182 @Override
0183 public default Spliterator<T> spliterator() {
0184 return new SeqSpliterator<T>(this);
0185 }
0186
0187 /**
0188 * Returns {@code true} if this sequence contains the specified element.
0189 *
0190 * @param element element whose presence in this sequence is to be tested.
0191 * The tested element can be {@code null}.
0192 * @return {@code true} if this sequence contains the specified element
0193 */
0194 public default boolean contains(final Object element) {
0195 return indexOf(element) != -1;
0196 }
0197
0198 /**
0199 * Returns the index of the first occurrence of the specified element
0200 * in this sequence, or -1 if this sequence does not contain the element.
0201 *
0202 * @param element element to search for, can be {@code null}
0203 * @return the index of the first occurrence of the specified element in
0204 * this sequence, or -1 if this sequence does not contain the element
0205 */
0206 public default int indexOf(final Object element) {
0207 return indexOf(element, 0, length());
0208 }
0209
0210 /**
0211 * Returns the index of the first occurrence of the specified element
0212 * in this sequence, or -1 if this sequence does not contain the element.
0213 *
0214 * @param element element to search for, can be {@code null}
0215 * @param start the start index (inclusively) for the element search.
0216 * @return the index of the first occurrence of the specified element in
0217 * this sequence, or -1 if this sequence does not contain the element
0218 * @throws IndexOutOfBoundsException for an illegal end point index value
0219 * ({@code start < 0 || start > length()}).
0220 */
0221 public default int indexOf(final Object element, final int start) {
0222 return indexOf(element, start, length());
0223 }
0224
0225 /**
0226 * Returns the index of the first occurrence of the specified element
0227 * in this sequence, or -1 if this sequence does not contain the element.
0228 *
0229 * @param element element to search for, can be {@code null}
0230 * @param start the start index (inclusively) for the element search.
0231 * @param end the end index (exclusively) for the element search.
0232 * @return the index of the first occurrence of the specified element in
0233 * this sequence, or -1 if this sequence does not contain the element
0234 * @throws IndexOutOfBoundsException for an illegal end point index value
0235 * ({@code start < 0 || end > length() || start > end}).
0236 */
0237 public default int indexOf(final Object element, final int start, final int end) {
0238 return element != null
0239 ? indexWhere(element::equals, start, end)
0240 : indexWhere(Objects::isNull, start, end);
0241 }
0242
0243 /**
0244 * <p>
0245 * Returns the index of the first element on which the given predicate
0246 * returns {@code true}, or -1 if the predicate returns false for every
0247 * sequence element.
0248 * </p>
0249 * <pre>{@code
0250 * // Finding index of first null value.
0251 * final int index = seq.indexOf(o -> o == null);
0252 *
0253 * // Assert of no null values.
0254 * assert (sequence.indexOf(o -> o == null) == -1);
0255 * }</pre>
0256 *
0257 * @param predicate the search predicate.
0258 * @return the index of the first element on which the given predicate
0259 * returns {@code true}, or -1 if the predicate returns {@code false}
0260 * for every sequence element.
0261 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0262 */
0263 public default int indexWhere(final Predicate<? super T> predicate) {
0264 return indexWhere(predicate, 0, length());
0265 }
0266
0267 /**
0268 * <p>
0269 * Returns the index of the first element on which the given predicate
0270 * returns {@code true}, or -1 if the predicate returns false for every
0271 * sequence element.
0272 * </p>
0273 * <pre>{@code
0274 * // Finding index of first null value.
0275 * final int index = seq.indexOf(o -> o == null);
0276 *
0277 * // Assert of no null values.
0278 * assert (sequence.indexOf(o -> o == null) == -1);
0279 * }</pre>
0280 *
0281 * @param predicate the search predicate.
0282 * @param start the search start index
0283 * @return the index of the first element on which the given predicate
0284 * returns {@code true}, or -1 if the predicate returns {@code false}
0285 * for every sequence element.
0286 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0287 * @throws IndexOutOfBoundsException for an illegal end point index value
0288 * ({@code start < 0 || start > length()}).
0289 */
0290 public default int indexWhere(
0291 final Predicate<? super T> predicate,
0292 final int start
0293 ) {
0294 return indexWhere(predicate, start, length());
0295 }
0296
0297 /**
0298 * <p>
0299 * Returns the index of the first element on which the given predicate
0300 * returns {@code true}, or -1 if the predicate returns false for every
0301 * sequence element.
0302 * </p>
0303 * <pre>{@code
0304 * // Finding index of first null value.
0305 * final int index = seq.indexOf(o -> o == null);
0306 *
0307 * // Assert of no null values.
0308 * assert (sequence.indexOf(o -> o == null) == -1);
0309 * }</pre>
0310 *
0311 * @param predicate the search predicate.
0312 * @param start the search start index
0313 * @param end the search end index
0314 * @return the index of the first element on which the given predicate
0315 * returns {@code true}, or -1 if the predicate returns {@code false}
0316 * for every sequence element.
0317 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0318 * @throws IndexOutOfBoundsException for an illegal end point index value
0319 * ({@code start < 0 || end > length() || start > end}).
0320 */
0321 public default int indexWhere(
0322 final Predicate<? super T> predicate,
0323 final int start,
0324 final int end
0325 ) {
0326 requireNonNull(predicate, "Predicate");
0327 checkIndex(start, end, length());
0328
0329 int index = -1;
0330 for (int i = start; i < end && index == -1; ++i) {
0331 if (predicate.test(get(i))) {
0332 index = i;
0333 }
0334 }
0335 return index;
0336 }
0337
0338 /**
0339 * Returns the index of the last occurrence of the specified element
0340 * in this sequence, or -1 if this sequence does not contain the element.
0341 *
0342 * @param element element to search for, can be {@code null}
0343 * @return the index of the last occurrence of the specified element in
0344 * this sequence, or -1 if this sequence does not contain the element
0345 */
0346 public default int lastIndexOf(final Object element) {
0347 return lastIndexOf(element, 0, length());
0348 }
0349
0350 /**
0351 * Returns the index of the last occurrence of the specified element
0352 * in this sequence, or -1 if this sequence does not contain the element.
0353 *
0354 * @param element element to search for, can be {@code null}
0355 * @param end the search end index
0356 * @return the index of the last occurrence of the specified element in
0357 * this sequence, or -1 if this sequence does not contain the element
0358 * @throws IndexOutOfBoundsException for an illegal end point index value
0359 * ({@code end < 0 || end > length()}).
0360 */
0361 public default int lastIndexOf(final Object element, final int end) {
0362 return lastIndexOf(element, 0, end);
0363 }
0364
0365 /**
0366 * Returns the index of the last occurrence of the specified element
0367 * in this sequence, or -1 if this sequence does not contain the element.
0368 *
0369 * @param element element to search for, can be {@code null}
0370 * @param start the search start index
0371 * @param end the search end index
0372 * @return the index of the last occurrence of the specified element in
0373 * this sequence, or -1 if this sequence does not contain the element
0374 * @throws IndexOutOfBoundsException for an illegal end point index value
0375 * ({@code start < 0 || end > length() || start > end}).
0376 */
0377 public default int lastIndexOf(
0378 final Object element,
0379 final int start,
0380 final int end
0381 ) {
0382 return element != null
0383 ? lastIndexWhere(element::equals, start, end)
0384 : lastIndexWhere(Objects::isNull, start, end);
0385 }
0386
0387 /**
0388 * Returns the index of the last element on which the given predicate
0389 * returns {@code true}, or -1 if the predicate returns false for every
0390 * sequence element.
0391 *
0392 * @param predicate the search predicate.
0393 * @return the index of the last element on which the given predicate
0394 * returns {@code true}, or -1 if the predicate returns false for
0395 * every sequence element.
0396 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0397 */
0398 public default int lastIndexWhere(final Predicate<? super T> predicate) {
0399 return lastIndexWhere(predicate, 0, length());
0400 }
0401
0402 /**
0403 * Returns the index of the last element on which the given predicate
0404 * returns {@code true}, or -1 if the predicate returns false for every
0405 * sequence element.
0406 *
0407 * @param predicate the search predicate.
0408 * @param end the search end index
0409 * @return the index of the last element on which the given predicate
0410 * returns {@code true}, or -1 if the predicate returns false for
0411 * every sequence element.
0412 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0413 * @throws IndexOutOfBoundsException for an illegal end point index value
0414 * ({@code end < 0 || end > length()}).
0415 */
0416 public default int lastIndexWhere(
0417 final Predicate<? super T> predicate,
0418 final int end
0419 ) {
0420 return lastIndexWhere(predicate, 0, end);
0421 }
0422
0423 /**
0424 * Returns the index of the last element on which the given predicate
0425 * returns {@code true}, or -1 if the predicate returns false for every
0426 * sequence element.
0427 *
0428 * @param predicate the search predicate.
0429 * @param start the search start index
0430 * @param end the search end index
0431 * @return the index of the last element on which the given predicate
0432 * returns {@code true}, or -1 if the predicate returns false for
0433 * every sequence element.
0434 * @throws NullPointerException if the given {@code predicate} is {@code null}.
0435 * @throws IndexOutOfBoundsException for an illegal end point index value
0436 * ({@code start < 0 || end > length() || start > end}).
0437 */
0438 public default int lastIndexWhere(
0439 final Predicate<? super T> predicate,
0440 final int start,
0441 final int end
0442 ) {
0443 requireNonNull(predicate, "Predicate");
0444 checkIndex(start, end, length());
0445
0446 int index = -1;
0447 for (int i = end; --i >= start && index == -1;) {
0448 if (predicate.test(get(i))) {
0449 index = i;
0450 }
0451 }
0452 return index;
0453 }
0454
0455 /**
0456 * Builds a new sequence by applying a function to all elements of this
0457 * sequence.
0458 *
0459 * @param <B> the element type of the returned collection.
0460 * @param mapper the function to apply to each element.
0461 * @return a new sequence of type That resulting from applying the given
0462 * function f to each element of this sequence and collecting the
0463 * results.
0464 * @throws NullPointerException if the element {@code mapper} is
0465 * {@code null}.
0466 */
0467 public <B> Seq<B> map(final Function<? super T, ? extends B> mapper);
0468
0469 /**
0470 * Return a <i>new</i> {@code Seq} with the given {@code values} appended.
0471 *
0472 * @since 3.4
0473 *
0474 * @param values the values to append
0475 * @return a <i>new</i> {@code Seq} with the elements of {@code this}
0476 * sequence and the given {@code values} appended.
0477 * @throws NullPointerException if the given {@code values} array is
0478 * {@code null}
0479 */
0480 @SuppressWarnings("unchecked")
0481 public default Seq<T> append(final T... values) {
0482 return append(Seq.of(values));
0483 }
0484
0485 /**
0486 * Return a <i>new</i> {@code Seq} with the given {@code values} appended.
0487 *
0488 * @since 3.4
0489 *
0490 * @param values the values to append
0491 * @return a <i>new</i> {@code Seq} with the elements of {@code this}
0492 * sequence and the given {@code values} appended.
0493 * @throws NullPointerException if the given {@code values} iterable is
0494 * {@code null}
0495 */
0496 public Seq<T> append(final Iterable<? extends T> values);
0497
0498 /**
0499 * Return a <i>new</i> {@code Seq} with the given {@code values} prepended.
0500 *
0501 * @since 3.4
0502 *
0503 * @param values the values to append
0504 * @return a <i>new</i> {@code Seq} with the elements of {@code this}
0505 * sequence and the given {@code values} prepended.
0506 * @throws NullPointerException if the given {@code values} array is
0507 * {@code null}
0508 */
0509 @SuppressWarnings("unchecked")
0510 public default Seq<T> prepend(final T... values) {
0511 return prepend(Seq.of(values));
0512 }
0513
0514 /**
0515 * Return a <i>new</i> {@code Seq} with the given {@code values} prepended.
0516 *
0517 * @since 3.4
0518 *
0519 * @param values the values to append
0520 * @return a <i>new</i> {@code Seq} with the elements of {@code this}
0521 * sequence and the given {@code values} prepended.
0522 * @throws NullPointerException if the given {@code values} array is
0523 * {@code null}
0524 */
0525 public Seq<T> prepend(final Iterable<? extends T> values);
0526
0527 /**
0528 * Returns a fixed-size list backed by the specified sequence. (Changes to
0529 * the returned list "write through" to the array.) The returned list is
0530 * fixed size, serializable and implements {@link RandomAccess}.
0531 *
0532 * @return a list view of this sequence
0533 */
0534 public default List<T> asList() {
0535 return new SeqList<>(this);
0536 }
0537
0538 /**
0539 * Return an array containing all of the elements in this sequence in right
0540 * order. The returned array will be "safe" in that no references to it
0541 * are maintained by this sequence. (In other words, this method must allocate
0542 * a new array.) The caller is thus free to modify the returned array.
0543 *
0544 * @see java.util.Collection#toArray()
0545 *
0546 * @return an array containing all of the elements in this list in right
0547 * order
0548 */
0549 public default Object[] toArray() {
0550 final Object[] array = new Object[size()];
0551 for (int i = size(); --i >= 0;) {
0552 array[i] = get(i);
0553 }
0554 return array;
0555 }
0556
0557 /**
0558 * Return an array containing all of the elements in this sequence in right
0559 * order; the runtime type of the returned array is that of the specified
0560 * array. If this sequence fits in the specified array, it is returned
0561 * therein. Otherwise, a new array is allocated with the runtime type of the
0562 * specified array and the length of this array.
0563 * <p>
0564 * If this sequence fits in the specified array with room to spare (i.e.,
0565 * the array has more elements than this array), the element in the array
0566 * immediately following the end of this array is set to null. (This is
0567 * useful in determining the length of the array only if the caller knows
0568 * that the list does not contain any null elements.)
0569 *
0570 * @see java.util.Collection#toArray(Object[])
0571 *
0572 * @param <B> the runtime type of the array to contain the sequence
0573 * @param array the array into which the elements of this array are to be
0574 * stored, if it is big enough; otherwise, a new array of the same
0575 * runtime type is allocated for this purpose.
0576 * @return an array containing the elements of this array
0577 * @throws ArrayStoreException if the runtime type of the specified array is
0578 * not a super type of the runtime type of every element in this
0579 * array
0580 * @throws NullPointerException if the given {@code array} is {@code null}.
0581 */
0582 @SuppressWarnings("unchecked")
0583 public default <B> B[] toArray(final B[] array) {
0584 if (array.length < length()) {
0585 final Object[] copy = (Object[])java.lang.reflect.Array
0586 .newInstance(array.getClass().getComponentType(), length());
0587
0588 for (int i = length(); --i >= 0;) {
0589 copy[i] = get(i);
0590 }
0591
0592 return (B[])copy;
0593 }
0594
0595 for (int i = 0, n = length(); i < n; ++i) {
0596 ((Object[])array)[i] = get(i);
0597 }
0598 if (array.length > length()) {
0599 array[length()] = null;
0600 }
0601
0602 return array;
0603 }
0604
0605 /**
0606 * Returns an array containing the elements of this sequence, using the
0607 * provided generator function to allocate the returned array.
0608 *
0609 * @since 4.4
0610 *
0611 * @param generator a function which produces a new array of the desired
0612 * type and the provided length
0613 * @param <B> the element type of the resulting array
0614 * @return an array containing the elements in {@code this} sequence
0615 * @throws ArrayStoreException if the runtime type of the specified array is
0616 * not a super type of the runtime type of every element in this
0617 * array
0618 * @throws NullPointerException if the given {@code generator} is {@code null}.
0619 */
0620 public default <B> B[] toArray(final IntFunction<B[]> generator) {
0621 return toArray(generator.apply(length()));
0622 }
0623
0624 /**
0625 * Returns a view of the portion of this sequence between the specified
0626 * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
0627 * and {@code end} are equal, the returned sequence has the length zero.)
0628 * The returned sequence is backed by this sequence, so non-structural
0629 * changes in the returned sequence are reflected in this sequence, and
0630 * vice-versa.
0631 * <p>
0632 * This method eliminates the need for explicit range operations (of the
0633 * populationSort that commonly exist for arrays). Any operation that
0634 * expects an sequence can be used as a range operation by passing an sub
0635 * sequence view instead of an whole sequence.
0636 *
0637 * @param start low end point (inclusive) of the sub array.
0638 * @return a view of the specified range within this array.
0639 * @throws IndexOutOfBoundsException for an illegal end point index value
0640 * ({@code start < 0 || start > length()}).
0641 */
0642 public Seq<T> subSeq(final int start);
0643
0644 /**
0645 * Returns a view of the portion of this sequence between the specified
0646 * {@code start}, inclusive, and {@code end}, exclusive. (If {@code start}
0647 * and {@code end} are equal, the returned sequence has the length zero.)
0648 * The returned sequence is backed by this sequence, so non-structural
0649 * changes in the returned sequence are reflected in this array, and
0650 * vice-versa.
0651 * <p>
0652 * This method eliminates the need for explicit range operations (of the
0653 * populationSort that commonly exist for arrays). Any operation that
0654 * expects an array can be used as a range operation by passing an sub
0655 * sequence view instead of an whole sequence.
0656 *
0657 * @param start low end point (inclusive) of the sub sequence.
0658 * @param end high end point (exclusive) of the sub sequence.
0659 * @return a view of the specified range within this sequence.
0660 * @throws IndexOutOfBoundsException for an illegal end point index value
0661 * ({@code start < 0 || end > length() || start > end}).
0662 */
0663 public Seq<T> subSeq(final int start, final int end);
0664
0665 /**
0666 * Test whether the given array is sorted in ascending order.
0667 *
0668 * @return {@code true} if the given {@code array} is sorted in ascending
0669 * order, {@code false} otherwise.
0670 * @throws NullPointerException if the given array or one of it's element is
0671 * {@code null}.
0672 */
0673 @SuppressWarnings("unchecked")
0674 public default boolean isSorted() {
0675 boolean sorted = true;
0676 for (int i = 0, n = length() - 1; i < n && sorted; ++i) {
0677 sorted = ((Comparable<T>)get(i)).compareTo(get(i + 1)) <= 0;
0678 }
0679
0680 return sorted;
0681 }
0682
0683 /**
0684 * Test whether the given array is sorted in ascending order. The order of
0685 * the array elements is defined by the given comparator.
0686 *
0687 * @param comparator the comparator which defines the order.
0688 * @return {@code true} if the given {@code array} is sorted in ascending
0689 * order, {@code false} otherwise.
0690 * @throws NullPointerException if the given array or one of it's element or
0691 * the comparator is {@code null}.
0692 */
0693 public default boolean isSorted(final Comparator<? super T> comparator) {
0694 boolean sorted = true;
0695 for (int i = 0, n = length() - 1; i < n && sorted; ++i) {
0696 sorted = comparator.compare(get(i), get(i + 1)) <= 0;
0697 }
0698
0699 return sorted;
0700 }
0701
0702 /**
0703 * Return this sequence as {@code MSeq} instance. If {@code this} is not a
0704 * {@code MSeq} a new seq is created.
0705 *
0706 * @since 3.8
0707 *
0708 * @return a {@code MSeq} with this values
0709 */
0710 public default MSeq<T> asMSeq() {
0711 return this instanceof MSeq ? (MSeq<T>)this : MSeq.of(this);
0712 }
0713
0714 /**
0715 * Return this sequence as {@code ISeq} instance. If {@code this} is not a
0716 * {@code ISeq} a new seq is created.
0717 *
0718 * @since 3.8
0719 *
0720 * @return a {@code ISeq} with this values
0721 */
0722 public default ISeq<T> asISeq() {
0723 return this instanceof ISeq ? (ISeq<T>)this : ISeq.of(this);
0724 }
0725
0726 /**
0727 * Returns the hash code value for this sequence. The hash code is defined
0728 * as followed:
0729 *
0730 * <pre>{@code
0731 * int hashCode = 1;
0732 * final Iterator<E> it = seq.iterator();
0733 * while (it.hasNext()) {
0734 * final E obj = it.next();
0735 * hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
0736 * }
0737 * }</pre>
0738 *
0739 * @see List#hashCode()
0740 * @see Seq#hashCode(Seq)
0741 *
0742 * @return the hash code value for this list
0743 */
0744 @Override
0745 public int hashCode();
0746
0747 /**
0748 * Compares the specified object with this sequence for equality. Returns
0749 * true if and only if the specified object is also a sequence, both
0750 * sequence have the same size, and all corresponding pairs of elements in
0751 * the two sequences are equal. (Two elements e1 and e2 are equal if
0752 * (e1==null ? e2==null : e1.equals(e2)).) This definition ensures that the
0753 * equals method works properly across different implementations of the Seq
0754 * interface.
0755 *
0756 * @see List#equals(Object)
0757 * @see Seq#equals(Seq, Object)
0758 *
0759 * @param object the object to be compared for equality with this sequence.
0760 * @return {@code true} if the specified object is equal to this sequence,
0761 * {@code false} otherwise.
0762 */
0763 @Override
0764 public boolean equals(final Object object);
0765
0766 /**
0767 * Create a string representation of the given sequence.
0768 *
0769 * @param prefix the prefix of the string representation; e.g {@code '['}.
0770 * @param separator the separator of the array elements; e.g. {@code ','}.
0771 * @param suffix the suffix of the string representation; e.g. {@code ']'}.
0772 * @return the string representation of this sequence.
0773 */
0774 public default String toString(
0775 final String prefix,
0776 final String separator,
0777 final String suffix
0778 ) {
0779 return stream()
0780 .map(Objects::toString)
0781 .collect(joining(separator, prefix, suffix));
0782 }
0783
0784 /**
0785 * Create a string representation of the given sequence.
0786 *
0787 * @param separator the separator of the array elements; e.g. {@code ','}.
0788 * @return the string representation of this sequence.
0789 */
0790 public default String toString(final String separator) {
0791 return toString("", separator, "");
0792 }
0793
0794 /**
0795 * Unified method for calculating the hash code of every {@link Seq}
0796 * implementation. The hash code is defined as followed:
0797 *
0798 * <pre>{@code
0799 * int hashCode = 1;
0800 * final Iterator<E> it = seq.iterator();
0801 * while (it.hasNext()) {
0802 * final E obj = it.next();
0803 * hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
0804 * }
0805 * }</pre>
0806 *
0807 * @see Seq#hashCode()
0808 * @see List#hashCode()
0809 *
0810 * @param seq the sequence to calculate the hash code for.
0811 * @return the hash code of the given sequence.
0812 */
0813 public static int hashCode(final Seq<?> seq) {
0814 int hash = 1;
0815 for (Object element : seq) {
0816 hash = 31*hash + (element == null ? 0: element.hashCode());
0817 }
0818 return hash;
0819 }
0820
0821 /**
0822 * Unified method for compare to sequences for equality.
0823 *
0824 * @see Seq#equals(Object)
0825 *
0826 * @param seq the sequence to test for equality.
0827 * @param obj the object to test for equality with the sequence.
0828 * @return {@code true} if the given objects are sequences and contain the
0829 * same objects in the same order, {@code false} otherwise.
0830 */
0831 public static boolean equals(final Seq<?> seq, final Object obj) {
0832 if (obj == seq) {
0833 return true;
0834 }
0835 if (!(obj instanceof Seq)) {
0836 return false;
0837 }
0838
0839 final Seq<?> other = (Seq<?>)obj;
0840 boolean equals = seq.length() == other.length();
0841 for (int i = seq.length(); equals && --i >= 0;) {
0842 final Object element = seq.get(i);
0843 if (element != null) {
0844 equals = element.equals(other.get(i));
0845 } else {
0846 equals = other.get(i) == null;
0847 }
0848 }
0849 return equals;
0850 }
0851
0852 /* *************************************************************************
0853 * Some static helper methods.
0854 * ************************************************************************/
0855
0856 /**
0857 * Return a sequence whose elements are all the elements of the first
0858 * element followed by all the elements of the sequence.
0859 *
0860 * @since 5.0
0861 *
0862 * @param a the first element
0863 * @param b the appending sequence
0864 * @param <T> the type of the sequence elements
0865 * @return the concatenation of the two inputs
0866 * @throws NullPointerException if one of the second arguments is
0867 * {@code null}
0868 */
0869 @SuppressWarnings("unchecked")
0870 public static <T> Seq<T> concat(
0871 final T a,
0872 final Seq<? extends T> b
0873 ) {
0874 return ((Seq<T>)b).prepend(a);
0875 }
0876
0877 /**
0878 * Return a sequence whose elements are all the elements of the first
0879 * sequence followed by all the elements of the vararg array.
0880 *
0881 * @since 5.0
0882 *
0883 * @param a the first sequence
0884 * @param b the vararg elements
0885 * @param <T> the type of the sequence elements
0886 * @return the concatenation of the two inputs
0887 * @throws NullPointerException if one of the arguments is {@code null}
0888 */
0889 @SuppressWarnings("unchecked")
0890 public static <T> Seq<T> concat(
0891 final Seq<? extends T> a,
0892 final T... b
0893 ) {
0894 return ((Seq<T>)a).append(b);
0895 }
0896
0897 /**
0898 * Return a sequence whose elements are all the elements of the first
0899 * sequence followed by all the elements of the second sequence.
0900 *
0901 * @since 5.0
0902 *
0903 * @param a the first sequence
0904 * @param b the second sequence
0905 * @param <T> the type of the sequence elements
0906 * @return the concatenation of the two input sequences
0907 * @throws NullPointerException if one of the arguments is {@code null}
0908 */
0909 @SuppressWarnings("unchecked")
0910 public static <T> Seq<T> concat(
0911 final Seq<? extends T> a,
0912 final Seq<? extends T> b
0913 ) {
0914 return ((Seq<T>)a).append(b);
0915 }
0916
0917 /* *************************************************************************
0918 * Some static factory methods.
0919 * ************************************************************************/
0920
0921 /**
0922 * Single instance of an empty {@code Seq}.
0923 *
0924 * @since 3.3
0925 */
0926 public static final Seq<?> EMPTY = ISeq.EMPTY;
0927
0928 /**
0929 * Return an empty {@code Seq}.
0930 *
0931 * @since 3.3
0932 *
0933 * @param <T> the element type of the returned {@code Seq}.
0934 * @return an empty {@code Seq}.
0935 */
0936 public static <T> Seq<T> empty() {
0937 return ISeq.empty();
0938 }
0939
0940 /**
0941 * Returns a {@code Collector} that accumulates the input elements into a
0942 * new {@code Seq}.
0943 *
0944 * @param <T> the type of the input elements
0945 * @return a {@code Collector} which collects all the input elements into a
0946 * {@code Seq}, in encounter order
0947 */
0948 public static <T> Collector<T, ?, Seq<T>> toSeq() {
0949 return Collector.of(
0950 (Supplier<List<T>>)ArrayList::new,
0951 List::add,
0952 (left, right) -> { left.addAll(right); return left; },
0953 Seq::of
0954 );
0955 }
0956
0957 /**
0958 * Returns a {@code Collector} that accumulates the last {@code n} input
0959 * elements into a new {@code Seq}.
0960 *
0961 * @since 5.0
0962 *
0963 * @param maxSize the maximal size of the collected sequence
0964 * @param <T> the type of the input elements
0965 * @return a {@code Collector} which collects maximal {@code maxSize} of the
0966 * input elements into an {@code ISeq}, in encounter order
0967 * @throws IllegalArgumentException if the {@code maxSize} is negative
0968 */
0969 public static <T> Collector<T, ?, Seq<T>> toSeq(final int maxSize) {
0970 return Seqs.toSeq(maxSize, Buffer::toSeq);
0971 }
0972
0973 /**
0974 * Create a new {@code Seq} from the given values.
0975 *
0976 * @param <T> the element type
0977 * @param values the array values.
0978 * @return a new {@code Seq} with the given values.
0979 * @throws NullPointerException if the {@code values} array is {@code null}.
0980 */
0981 @SafeVarargs
0982 public static <T> Seq<T> of(final T... values) {
0983 return ISeq.of(values);
0984 }
0985
0986 /**
0987 * Create a new {@code Seq} from the given values.
0988 *
0989 * @param <T> the element type
0990 * @param values the array values.
0991 * @return a new {@code Seq} with the given values.
0992 * @throws NullPointerException if the {@code values} array is {@code null}.
0993 */
0994 public static <T> Seq<T> of(final Iterable<? extends T> values) {
0995 return ISeq.of(values);
0996 }
0997
0998 // /**
0999 // * Create a new {@code Seq} instance from the remaining elements of the
1000 // * given iterator.
1001 // *
1002 // * @since 3.3
1003 // *
1004 // * @param <T> the element type.
1005 // * @return a new {@code Seq} with the given remaining values.
1006 // * @throws NullPointerException if the {@code values} object is
1007 // * {@code null}.
1008 // */
1009 // public static <T> Seq<T> of(final Iterator<? extends T> values) {
1010 // final MSeq<T> seq = MSeq.of(values);
1011 // return seq.isEmpty() ? empty() : seq.toISeq();
1012 // }
1013
1014 /**
1015 * Creates a new sequence, which is filled with objects created be the given
1016 * {@code supplier}.
1017 *
1018 * @since 3.3
1019 *
1020 * @param <T> the element type of the sequence
1021 * @param supplier the {@code Supplier} which creates the elements, the
1022 * returned sequence is filled with
1023 * @param length the length of the returned sequence
1024 * @return a new sequence filled with elements given by the {@code supplier}
1025 * @throws NegativeArraySizeException if the given {@code length} is
1026 * negative
1027 * @throws NullPointerException if the given {@code supplier} is
1028 * {@code null}
1029 */
1030 static <T> Seq<T> of(Supplier<? extends T> supplier, final int length) {
1031 return ISeq.of(supplier, length);
1032 }
1033
1034
1035 /**
1036 * Returns a sequence backed by the specified list. (Changes to the given
1037 * list are "write through" to the returned sequence.) This method acts
1038 * as bridge between collection-based and sequence-based APIs.
1039 *
1040 * @since 4.2
1041 *
1042 * @param list the list containing the elements
1043 * @param <T> the element type
1044 * @return a sequence view of the given {@code list}
1045 * @throws NullPointerException if the given list is {@code null}
1046 */
1047 public static <T> Seq<T> viewOf(final List<? extends T> list) {
1048 return list.isEmpty()
1049 ? empty()
1050 : new SeqView<>(list);
1051 }
1052
1053 /**
1054 * Returns a fixed-size sequence backed by the specified array. (Changes to
1055 * the given array are "write through" to the returned sequence.) This
1056 * method acts as bridge between array-based and sequence-based APIs.
1057 *
1058 * @since 4.2
1059 *
1060 * @param array the array containing the sequence elements
1061 * @param <T> the element type
1062 * @return a sequence view of the given {@code array}
1063 * @throws NullPointerException if the given array is {@code null}
1064 */
1065 public static <T> Seq<T> viewOf(final T[] array) {
1066 return array.length == 0
1067 ? empty()
1068 : new SeqView<>(Arrays.asList(array));
1069 }
1070
1071 }
|