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