1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.collections4; 18 19 import java.lang.reflect.Array; 20 import java.lang.reflect.Method; 21 import java.util.ArrayList; 22 import java.util.Collection; 23 import java.util.Comparator; 24 import java.util.Dictionary; 25 import java.util.Enumeration; 26 import java.util.Iterator; 27 import java.util.List; 28 import java.util.ListIterator; 29 import java.util.Map; 30 import java.util.Objects; 31 import java.util.Spliterator; 32 import java.util.Spliterators; 33 import java.util.function.IntFunction; 34 import java.util.stream.Stream; 35 import java.util.stream.StreamSupport; 36 37 import org.apache.commons.collections4.functors.EqualPredicate; 38 import org.apache.commons.collections4.iterators.ArrayIterator; 39 import org.apache.commons.collections4.iterators.ArrayListIterator; 40 import org.apache.commons.collections4.iterators.BoundedIterator; 41 import org.apache.commons.collections4.iterators.CollatingIterator; 42 import org.apache.commons.collections4.iterators.EmptyIterator; 43 import org.apache.commons.collections4.iterators.EmptyListIterator; 44 import org.apache.commons.collections4.iterators.EmptyMapIterator; 45 import org.apache.commons.collections4.iterators.EmptyOrderedIterator; 46 import org.apache.commons.collections4.iterators.EmptyOrderedMapIterator; 47 import org.apache.commons.collections4.iterators.EnumerationIterator; 48 import org.apache.commons.collections4.iterators.FilterIterator; 49 import org.apache.commons.collections4.iterators.FilterListIterator; 50 import org.apache.commons.collections4.iterators.IteratorChain; 51 import org.apache.commons.collections4.iterators.IteratorEnumeration; 52 import org.apache.commons.collections4.iterators.IteratorIterable; 53 import org.apache.commons.collections4.iterators.LazyIteratorChain; 54 import org.apache.commons.collections4.iterators.ListIteratorWrapper; 55 import org.apache.commons.collections4.iterators.LoopingIterator; 56 import org.apache.commons.collections4.iterators.LoopingListIterator; 57 import org.apache.commons.collections4.iterators.NodeListIterator; 58 import org.apache.commons.collections4.iterators.ObjectArrayIterator; 59 import org.apache.commons.collections4.iterators.ObjectArrayListIterator; 60 import org.apache.commons.collections4.iterators.ObjectGraphIterator; 61 import org.apache.commons.collections4.iterators.PeekingIterator; 62 import org.apache.commons.collections4.iterators.PushbackIterator; 63 import org.apache.commons.collections4.iterators.SingletonIterator; 64 import org.apache.commons.collections4.iterators.SingletonListIterator; 65 import org.apache.commons.collections4.iterators.SkippingIterator; 66 import org.apache.commons.collections4.iterators.TransformIterator; 67 import org.apache.commons.collections4.iterators.UnmodifiableIterator; 68 import org.apache.commons.collections4.iterators.UnmodifiableListIterator; 69 import org.apache.commons.collections4.iterators.UnmodifiableMapIterator; 70 import org.apache.commons.collections4.iterators.ZippingIterator; 71 import org.w3c.dom.Node; 72 import org.w3c.dom.NodeList; 73 74 /** 75 * Provides static utility methods and decorators for {@link Iterator} 76 * instances. The implementations are provided in the iterators subpackage. 77 * 78 * @since 2.1 79 */ 80 public class IteratorUtils { 81 // validation is done in this class in certain cases because the 82 // public classes allow invalid states 83 84 /** 85 * An iterator over no elements. 86 */ 87 @SuppressWarnings("rawtypes") 88 public static final ResettableIterator EMPTY_ITERATOR = EmptyIterator.RESETTABLE_INSTANCE; 89 90 /** 91 * A list iterator over no elements. 92 */ 93 @SuppressWarnings("rawtypes") 94 public static final ResettableListIterator EMPTY_LIST_ITERATOR = EmptyListIterator.RESETTABLE_INSTANCE; 95 96 /** 97 * An ordered iterator over no elements. 98 */ 99 @SuppressWarnings("rawtypes") 100 public static final OrderedIterator EMPTY_ORDERED_ITERATOR = EmptyOrderedIterator.INSTANCE; 101 102 /** 103 * A map iterator over no elements. 104 */ 105 @SuppressWarnings("rawtypes") 106 public static final MapIterator EMPTY_MAP_ITERATOR = EmptyMapIterator.INSTANCE; 107 108 /** 109 * An ordered map iterator over no elements. 110 */ 111 @SuppressWarnings("rawtypes") 112 public static final OrderedMapIterator EMPTY_ORDERED_MAP_ITERATOR = EmptyOrderedMapIterator.INSTANCE; 113 /** 114 * Default delimiter used to delimit elements while converting an Iterator 115 * to its String representation. 116 */ 117 private static final String DEFAULT_TOSTRING_DELIMITER = ", "; 118 119 /** 120 * Gets an iterator over an object array. 121 * 122 * @param <E> the element type 123 * @param array the array over which to iterate 124 * @return an iterator over the array 125 * @throws NullPointerException if array is null 126 */ 127 public static <E> ResettableIterator<E> arrayIterator(final E... array) { 128 return new ObjectArrayIterator<>(array); 129 } 130 131 /** 132 * Gets an iterator over the end part of an object array. 133 * 134 * @param <E> the element type 135 * @param array the array over which to iterate 136 * @param start the index to start iterating at 137 * @return an iterator over part of the array 138 * @throws IndexOutOfBoundsException if start is less than zero or greater 139 * than the length of the array 140 * @throws NullPointerException if array is null 141 */ 142 public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start) { 143 return new ObjectArrayIterator<>(array, start); 144 } 145 146 /** 147 * Gets an iterator over part of an object array. 148 * 149 * @param <E> the element type 150 * @param array the array over which to iterate 151 * @param start the index to start iterating at 152 * @param end the index to finish iterating at 153 * @return an iterator over part of the array 154 * @throws IndexOutOfBoundsException if array bounds are invalid 155 * @throws IllegalArgumentException if end is before start 156 * @throws NullPointerException if array is null 157 */ 158 public static <E> ResettableIterator<E> arrayIterator(final E[] array, final int start, final int end) { 159 return new ObjectArrayIterator<>(array, start, end); 160 } 161 162 /** 163 * Gets an iterator over an object or primitive array. 164 * <p> 165 * This method will handle primitive arrays as well as object arrays. 166 * The primitives will be wrapped in the appropriate wrapper class. 167 * </p> 168 * 169 * @param <E> the element type 170 * @param array the array over which to iterate 171 * @return an iterator over the array 172 * @throws IllegalArgumentException if the array is not an array 173 * @throws NullPointerException if array is null 174 */ 175 public static <E> ResettableIterator<E> arrayIterator(final Object array) { 176 return new ArrayIterator<>(array); 177 } 178 179 /** 180 * Gets an iterator over the end part of an object or primitive array. 181 * <p> 182 * This method will handle primitive arrays as well as object arrays. 183 * The primitives will be wrapped in the appropriate wrapper class. 184 * </p> 185 * 186 * @param <E> the element type 187 * @param array the array over which to iterate 188 * @param start the index to start iterating at 189 * @return an iterator over part of the array 190 * @throws IllegalArgumentException if the array is not an array 191 * @throws IndexOutOfBoundsException if start is less than zero or greater 192 * than the length of the array 193 * @throws NullPointerException if array is null 194 */ 195 public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start) { 196 return new ArrayIterator<>(array, start); 197 } 198 199 /** 200 * Gets an iterator over part of an object or primitive array. 201 * <p> 202 * This method will handle primitive arrays as well as object arrays. 203 * The primitives will be wrapped in the appropriate wrapper class. 204 * </p> 205 * 206 * @param <E> the element type 207 * @param array the array over which to iterate 208 * @param start the index to start iterating at 209 * @param end the index to finish iterating at 210 * @return an iterator over part of the array 211 * @throws IllegalArgumentException if the array is not an array or end is before start 212 * @throws IndexOutOfBoundsException if array bounds are invalid 213 * @throws NullPointerException if array is null 214 */ 215 public static <E> ResettableIterator<E> arrayIterator(final Object array, final int start, final int end) { 216 return new ArrayIterator<>(array, start, end); 217 } 218 219 /** 220 * Gets a list iterator over an object array. 221 * 222 * @param <E> the element type 223 * @param array the array over which to iterate 224 * @return a list iterator over the array 225 * @throws NullPointerException if array is null 226 */ 227 public static <E> ResettableListIterator<E> arrayListIterator(final E... array) { 228 return new ObjectArrayListIterator<>(array); 229 } 230 231 /** 232 * Gets a list iterator over the end part of an object array. 233 * 234 * @param <E> the element type 235 * @param array the array over which to iterate 236 * @param start the index to start iterating at 237 * @return a list iterator over part of the array 238 * @throws IndexOutOfBoundsException if start is less than zero 239 * @throws NullPointerException if array is null 240 */ 241 public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start) { 242 return new ObjectArrayListIterator<>(array, start); 243 } 244 245 /** 246 * Gets a list iterator over part of an object array. 247 * 248 * @param <E> the element type 249 * @param array the array over which to iterate 250 * @param start the index to start iterating at 251 * @param end the index to finish iterating at 252 * @return a list iterator over part of the array 253 * @throws IndexOutOfBoundsException if array bounds are invalid 254 * @throws IllegalArgumentException if end is before start 255 * @throws NullPointerException if array is null 256 */ 257 public static <E> ResettableListIterator<E> arrayListIterator(final E[] array, final int start, final int end) { 258 return new ObjectArrayListIterator<>(array, start, end); 259 } 260 261 /** 262 * Gets a list iterator over an object or primitive array. 263 * <p> 264 * This method will handle primitive arrays as well as object arrays. 265 * The primitives will be wrapped in the appropriate wrapper class. 266 * </p> 267 * 268 * @param <E> the element type 269 * @param array the array over which to iterate 270 * @return a list iterator over the array 271 * @throws IllegalArgumentException if the array is not an array 272 * @throws NullPointerException if array is null 273 */ 274 public static <E> ResettableListIterator<E> arrayListIterator(final Object array) { 275 return new ArrayListIterator<>(array); 276 } 277 278 /** 279 * Gets a list iterator over the end part of an object or primitive array. 280 * <p> 281 * This method will handle primitive arrays as well as object arrays. 282 * The primitives will be wrapped in the appropriate wrapper class. 283 * </p> 284 * 285 * @param <E> the element type 286 * @param array the array over which to iterate 287 * @param start the index to start iterating at 288 * @return a list iterator over part of the array 289 * @throws IllegalArgumentException if the array is not an array 290 * @throws IndexOutOfBoundsException if start is less than zero 291 * @throws NullPointerException if array is null 292 */ 293 public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start) { 294 return new ArrayListIterator<>(array, start); 295 } 296 297 /** 298 * Gets a list iterator over part of an object or primitive array. 299 * <p> 300 * This method will handle primitive arrays as well as object arrays. 301 * The primitives will be wrapped in the appropriate wrapper class. 302 * </p> 303 * 304 * @param <E> the element type 305 * @param array the array over which to iterate 306 * @param start the index to start iterating at 307 * @param end the index to finish iterating at 308 * @return a list iterator over part of the array 309 * @throws IllegalArgumentException if the array is not an array or end is before start 310 * @throws IndexOutOfBoundsException if array bounds are invalid 311 * @throws NullPointerException if array is null 312 */ 313 public static <E> ResettableListIterator<E> arrayListIterator(final Object array, final int start, final int end) { 314 return new ArrayListIterator<>(array, start, end); 315 } 316 317 /** 318 * Gets an enumeration that wraps an iterator. 319 * 320 * @param <E> the element type 321 * @param iterator the iterator to use, may not be null 322 * @return a new enumeration 323 * @throws NullPointerException if iterator is null 324 */ 325 public static <E> Enumeration<E> asEnumeration(final Iterator<? extends E> iterator) { 326 return new IteratorEnumeration<>(Objects.requireNonNull(iterator, "iterator")); 327 } 328 329 /** 330 * Gets an {@link Iterable} that wraps an iterator. The returned {@link Iterable} can be 331 * used for a single iteration. 332 * 333 * @param <E> the element type 334 * @param iterator the iterator to use, may not be null 335 * @return a new, single use {@link Iterable} 336 * @throws NullPointerException if iterator is null 337 */ 338 public static <E> Iterable<E> asIterable(final Iterator<? extends E> iterator) { 339 Objects.requireNonNull(iterator, "iterator"); 340 return new IteratorIterable<>(iterator, false); 341 } 342 343 /** 344 * Gets an iterator that provides an iterator view of the given enumeration. 345 * 346 * @param <E> the element type 347 * @param enumeration the enumeration to use, may not be null 348 * @return a new iterator 349 * @throws NullPointerException if enumeration is null 350 */ 351 public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration) { 352 return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration")); 353 } 354 355 /** 356 * Gets an iterator that provides an iterator view of the given enumeration 357 * that will remove elements from the specified collection. 358 * 359 * @param <E> the element type 360 * @param enumeration the enumeration to use, may not be null 361 * @param removeCollection the collection to remove elements from, may not be null 362 * @return a new iterator 363 * @throws NullPointerException if enumeration or removeCollection is null 364 */ 365 public static <E> Iterator<E> asIterator(final Enumeration<? extends E> enumeration, 366 final Collection<? super E> removeCollection) { 367 return new EnumerationIterator<>(Objects.requireNonNull(enumeration, "enumeration"), 368 Objects.requireNonNull(removeCollection, "removeCollection")); 369 } 370 371 /** 372 * Gets an iterable that wraps an iterator. The returned iterable can be 373 * used for multiple iterations. 374 * 375 * @param <E> the element type 376 * @param iterator the iterator to use, may not be null 377 * @return a new, multiple use iterable 378 * @throws NullPointerException if iterator is null 379 */ 380 public static <E> Iterable<E> asMultipleUseIterable(final Iterator<? extends E> iterator) { 381 Objects.requireNonNull(iterator, "iterator"); 382 return new IteratorIterable<>(iterator, true); 383 } 384 385 // Bounded 386 /** 387 * Decorates the specified iterator to return at most the given number 388 * of elements. 389 * 390 * @param <E> the element type 391 * @param iterator the iterator to decorate 392 * @param max the maximum number of elements returned by this iterator 393 * @return a new bounded iterator 394 * @throws NullPointerException if the iterator is null 395 * @throws IllegalArgumentException if max is negative 396 * @since 4.1 397 */ 398 public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator, final long max) { 399 return boundedIterator(iterator, 0, max); 400 } 401 402 /** 403 * Decorates the specified iterator to return at most the given number 404 * of elements, skipping all elements until the iterator reaches the 405 * position at {@code offset}. 406 * <p> 407 * The iterator is immediately advanced until it reaches the position at 408 * {@code offset}, incurring O(n) time. 409 * </p> 410 * 411 * @param <E> the element type 412 * @param iterator the iterator to decorate 413 * @param offset the index of the first element of the decorated iterator to return 414 * @param max the maximum number of elements returned by this iterator 415 * @return a new bounded iterator 416 * @throws NullPointerException if the iterator is null 417 * @throws IllegalArgumentException if either offset or max is negative 418 * @since 4.1 419 */ 420 public static <E> BoundedIterator<E> boundedIterator(final Iterator<? extends E> iterator, 421 final long offset, final long max) { 422 return new BoundedIterator<>(iterator, offset, max); 423 } 424 425 /** 426 * Gets an iterator that iterates through a collections of {@link Iterator}s 427 * one after another. 428 * 429 * @param <E> the element type 430 * @param iterators the iterators to use, not null or empty or contain nulls 431 * @return a combination iterator over the iterators 432 * @throws NullPointerException if iterators collection is null or contains a null 433 * @throws ClassCastException if the iterators collection contains the wrong object type 434 */ 435 public static <E> Iterator<E> chainedIterator(final Collection<? extends Iterator<? extends E>> iterators) { 436 return new IteratorChain<>(iterators); 437 } 438 439 /** 440 * Gets an iterator that iterates through an array of {@link Iterator}s 441 * one after another. 442 * 443 * @param <E> the element type 444 * @param iterators the iterators to use, not null or empty or contain nulls 445 * @return a combination iterator over the iterators 446 * @throws NullPointerException if iterators array is null or contains a null 447 */ 448 public static <E> Iterator<E> chainedIterator(final Iterator<? extends E>... iterators) { 449 return new IteratorChain<>(iterators); 450 } 451 452 /** 453 * Gets an iterator that iterates through two {@link Iterator}s 454 * one after another. 455 * 456 * @param <E> the element type 457 * @param iterator1 the first iterator to use, not null 458 * @param iterator2 the second iterator to use, not null 459 * @return a combination iterator over the iterators 460 * @throws NullPointerException if either iterator is null 461 */ 462 public static <E> Iterator<E> chainedIterator(final Iterator<? extends E> iterator1, 463 final Iterator<? extends E> iterator2) { 464 // keep a version with two iterators to avoid the following warning in client code (Java 5 & 6) 465 // "A generic array of E is created for a varargs parameter" 466 return new IteratorChain<>(iterator1, iterator2); 467 } 468 469 /** 470 * Gets an iterator that iterates through an {@link Iterator} of Iterators one after another. 471 * 472 * @param <E> the element type 473 * @param iterators the iterators to use, not null or empty or contain nulls 474 * @return a combination iterator over the iterators 475 * @throws NullPointerException if iterators collection is null or contains a null 476 * @throws ClassCastException if the iterators collection contains the wrong object type 477 * @since 4.5.0-M3 478 */ 479 public static <E> Iterator<E> chainedIterator(final Iterator<? extends Iterator<? extends E>> iterators) { 480 return new LazyIteratorChain<E>() { 481 482 @Override 483 protected Iterator<? extends E> nextIterator(final int count) { 484 return iterators.hasNext() ? iterators.next() : null; 485 } 486 487 }; 488 } 489 490 /** 491 * Gets an iterator that provides an ordered iteration over the elements 492 * contained in a collection of {@link Iterator}s. 493 * <p> 494 * Given two ordered {@link Iterator}s {@code A} and {@code B}, 495 * the {@link Iterator#next()} method will return the lesser of 496 * {@code A.next()} and {@code B.next()} and so on. 497 * </p> 498 * <p> 499 * The comparator is optional. If null is specified then natural order is used. 500 * </p> 501 * 502 * @param <E> the element type 503 * @param comparator the comparator to use, may be null for natural order 504 * @param iterators the iterators to use, not null or empty or contain nulls 505 * @return a combination iterator over the iterators 506 * @throws NullPointerException if iterators collection is null or contains a null 507 * @throws ClassCastException if the iterators collection contains the wrong object type 508 */ 509 public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator, 510 final Collection<Iterator<? extends E>> iterators) { 511 @SuppressWarnings("unchecked") 512 final Comparator<E> comp = 513 comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator; 514 return new CollatingIterator<>(comp, iterators); 515 } 516 517 /** 518 * Gets an iterator that provides an ordered iteration over the elements 519 * contained in an array of {@link Iterator}s. 520 * <p> 521 * Given two ordered {@link Iterator}s {@code A} and {@code B}, 522 * the {@link Iterator#next()} method will return the lesser of 523 * {@code A.next()} and {@code B.next()} and so on. 524 * </p> 525 * <p> 526 * The comparator is optional. If null is specified then natural order is used. 527 * </p> 528 * 529 * @param <E> the element type 530 * @param comparator the comparator to use, may be null for natural order 531 * @param iterators the iterators to use, not null or empty or contain nulls 532 * @return a combination iterator over the iterators 533 * @throws NullPointerException if iterators array is null or contains a null value 534 */ 535 public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator, 536 final Iterator<? extends E>... iterators) { 537 @SuppressWarnings("unchecked") 538 final Comparator<E> comp = 539 comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator; 540 return new CollatingIterator<>(comp, iterators); 541 } 542 543 /** 544 * Gets an iterator that provides an ordered iteration over the elements 545 * contained in a collection of ordered {@link Iterator}s. 546 * <p> 547 * Given two ordered {@link Iterator}s {@code A} and {@code B}, 548 * the {@link Iterator#next()} method will return the lesser of 549 * {@code A.next()} and {@code B.next()}. 550 * </p> 551 * <p> 552 * The comparator is optional. If null is specified then natural order is used. 553 * </p> 554 * 555 * @param <E> the element type 556 * @param comparator the comparator to use, may be null for natural order 557 * @param iterator1 the first iterators to use, not null 558 * @param iterator2 the first iterators to use, not null 559 * @return a combination iterator over the iterators 560 * @throws NullPointerException if either iterator is null 561 */ 562 public static <E> Iterator<E> collatedIterator(final Comparator<? super E> comparator, 563 final Iterator<? extends E> iterator1, 564 final Iterator<? extends E> iterator2) { 565 @SuppressWarnings("unchecked") 566 final Comparator<E> comp = 567 comparator == null ? ComparatorUtils.NATURAL_COMPARATOR : (Comparator<E>) comparator; 568 return new CollatingIterator<>(comp, iterator1, iterator2); 569 } 570 571 /** 572 * Checks if the object is contained in the given iterator. 573 * <p> 574 * A {@code null} or empty iterator returns false. 575 * </p> 576 * 577 * @param <E> the type of object the {@link Iterator} contains 578 * @param iterator the iterator to check, may be null 579 * @param object the object to check 580 * @return true if the object is contained in the iterator, false otherwise 581 * @since 4.1 582 */ 583 public static <E> boolean contains(final Iterator<E> iterator, final Object object) { 584 return matchesAny(iterator, EqualPredicate.equalPredicate(object)); 585 } 586 587 /** 588 * Gets an empty iterator. 589 * <p> 590 * This iterator is a valid iterator object that will iterate over nothing. 591 * </p> 592 * 593 * @param <E> the element type 594 * @return an iterator over nothing 595 */ 596 public static <E> ResettableIterator<E> emptyIterator() { 597 return EmptyIterator.<E>resettableEmptyIterator(); 598 } 599 600 /** 601 * Gets an empty list iterator. 602 * <p> 603 * This iterator is a valid list iterator object that will iterate 604 * over nothing. 605 * </p> 606 * 607 * @param <E> the element type 608 * @return a list iterator over nothing 609 */ 610 public static <E> ResettableListIterator<E> emptyListIterator() { 611 return EmptyListIterator.<E>resettableEmptyListIterator(); 612 } 613 614 /** 615 * Gets an empty map iterator. 616 * <p> 617 * This iterator is a valid map iterator object that will iterate 618 * over nothing. 619 * </p> 620 * 621 * @param <K> the key type 622 * @param <V> the value type 623 * @return a map iterator over nothing 624 */ 625 public static <K, V> MapIterator<K, V> emptyMapIterator() { 626 return EmptyMapIterator.<K, V>emptyMapIterator(); 627 } 628 629 /** 630 * Gets an empty ordered iterator. 631 * <p> 632 * This iterator is a valid iterator object that will iterate 633 * over nothing. 634 * </p> 635 * 636 * @param <E> the element type 637 * @return an ordered iterator over nothing 638 */ 639 public static <E> OrderedIterator<E> emptyOrderedIterator() { 640 return EmptyOrderedIterator.<E>emptyOrderedIterator(); 641 } 642 643 /** 644 * Gets an empty ordered map iterator. 645 * <p> 646 * This iterator is a valid map iterator object that will iterate 647 * over nothing. 648 * </p> 649 * 650 * @param <K> the key type 651 * @param <V> the value type 652 * @return a map iterator over nothing 653 */ 654 public static <K, V> OrderedMapIterator<K, V> emptyOrderedMapIterator() { 655 return EmptyOrderedMapIterator.<K, V>emptyOrderedMapIterator(); 656 } 657 658 /** 659 * Gets an iterator that filters another iterator. 660 * <p> 661 * The returned iterator will only return objects that match the specified 662 * filtering predicate. 663 * </p> 664 * 665 * @param <E> the element type 666 * @param iterator the iterator to use, not null 667 * @param predicate the predicate to use as a filter, not null 668 * @return a new filtered iterator 669 * @throws NullPointerException if either parameter is null 670 */ 671 public static <E> Iterator<E> filteredIterator(final Iterator<? extends E> iterator, 672 final Predicate<? super E> predicate) { 673 Objects.requireNonNull(iterator, "iterator"); 674 Objects.requireNonNull(predicate, "predicate"); 675 return new FilterIterator<>(iterator, predicate); 676 } 677 678 /** 679 * Gets a list iterator that filters another list iterator. 680 * <p> 681 * The returned iterator will only return objects that match the specified 682 * filtering predicate. 683 * </p> 684 * 685 * @param <E> the element type 686 * @param listIterator the list iterator to use, not null 687 * @param predicate the predicate to use as a filter, not null 688 * @return a new filtered iterator 689 * @throws NullPointerException if either parameter is null 690 */ 691 public static <E> ListIterator<E> filteredListIterator(final ListIterator<? extends E> listIterator, 692 final Predicate<? super E> predicate) { 693 694 Objects.requireNonNull(listIterator, "listIterator"); 695 Objects.requireNonNull(predicate, "predicate"); 696 return new FilterListIterator<>(listIterator, predicate); 697 } 698 699 /** 700 * Finds the first element in the given iterator which matches the given predicate. 701 * <p> 702 * A {@code null} or empty iterator returns null. 703 * </p> 704 * 705 * @param <E> the element type 706 * @param iterator the iterator to search, may be null 707 * @param predicate the predicate to use, must not be null 708 * @return the first element of the iterator which matches the predicate or null if none could be found 709 * @throws NullPointerException if predicate is null 710 * @since 4.1 711 */ 712 public static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate) { 713 return find(iterator, predicate, null); 714 } 715 716 /** 717 * Finds the first element in the given iterator which matches the given predicate. 718 * <p> 719 * A {@code null} or empty iterator returns {@code defaultValue}. 720 * </p> 721 * 722 * @param <E> the element type. 723 * @param iterator the iterator to search, may be null. 724 * @param predicate the predicate to use, must not be null. 725 * @param defaultValue the default value, may be null. 726 * @return the first element of the iterator which matches the predicate or null if none could be found. 727 * @throws NullPointerException if predicate is null. 728 */ 729 private static <E> E find(final Iterator<E> iterator, final Predicate<? super E> predicate, final E defaultValue) { 730 Objects.requireNonNull(predicate, "predicate"); 731 if (iterator != null) { 732 while (iterator.hasNext()) { 733 final E element = iterator.next(); 734 if (predicate.test(element)) { 735 return element; 736 } 737 } 738 } 739 return defaultValue; 740 } 741 742 /** 743 * Shortcut for {@code get(iterator, 0)}. 744 * <p> 745 * Returns the {@code first} value in {@link Iterator}, throwing 746 * {@code IndexOutOfBoundsException} if there is no such element. 747 * </p> 748 * <p> 749 * The Iterator is advanced to {@code 0} (or to the end, if 750 * {@code 0} exceeds the number of entries) as a side effect of this method. 751 * </p> 752 * @param <E> the type of object in the {@link Iterator} 753 * @param iterator the iterator to get a value from 754 * @return the first object 755 * @throws IndexOutOfBoundsException if the request is invalid 756 * @since 4.2 757 */ 758 public static <E> E first(final Iterator<E> iterator) { 759 return get(iterator, 0); 760 } 761 762 /** 763 * Applies the closure to each element of the provided iterator. 764 * 765 * @param <E> the element type 766 * @param iterator the iterator to use, may be null 767 * @param closure the closure to apply to each element, may not be null 768 * @throws NullPointerException if closure is null 769 * @since 4.1 770 */ 771 public static <E> void forEach(final Iterator<E> iterator, final Closure<? super E> closure) { 772 Objects.requireNonNull(closure, "closure"); 773 if (iterator != null) { 774 while (iterator.hasNext()) { 775 closure.accept(iterator.next()); 776 } 777 } 778 } 779 780 /** 781 * Executes the given closure on each but the last element in the iterator. 782 * <p> 783 * If the input iterator is null no change is made. 784 * </p> 785 * 786 * @param <E> the type of object the {@link Iterator} contains 787 * @param iterator the iterator to get the input from, may be null 788 * @param closure the closure to perform, may not be null 789 * @return the last element in the iterator, or null if iterator is null or empty 790 * @throws NullPointerException if closure is null 791 * @since 4.1 792 */ 793 public static <E> E forEachButLast(final Iterator<E> iterator, final Closure<? super E> closure) { 794 Objects.requireNonNull(closure, "closure"); 795 796 if (iterator != null) { 797 while (iterator.hasNext()) { 798 final E element = iterator.next(); 799 if (!iterator.hasNext()) { 800 return element; 801 } 802 closure.accept(element); 803 } 804 } 805 return null; 806 } 807 808 /** 809 * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element. 810 * <p> 811 * The Iterator is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method. 812 * </p> 813 * 814 * @param <E> the type of object in the {@link Iterator}. 815 * @param iterator the iterator to get a value from. 816 * @param index the index to get, 0-based. 817 * @return the object at the specified index. 818 * @throws IndexOutOfBoundsException if the index is invalid. 819 * @since 4.1 820 */ 821 public static <E> E get(final Iterator<E> iterator, final int index) { 822 return get(iterator, index, ioob -> { 823 throw new IndexOutOfBoundsException("Entry does not exist: " + ioob); 824 }); 825 } 826 827 /** 828 * Gets the {@code index}-th value in {@link Iterator}, throwing {@code IndexOutOfBoundsException} if there is no such element. 829 * <p> 830 * The Iterator is advanced to {@code index} (or to the end, if {@code index} exceeds the number of entries) as a side effect of this method. 831 * </p> 832 * 833 * @param <E> the type of object in the {@link Iterator} 834 * @param iterator the iterator to get a value from 835 * @param index the index to get, 0-based. 836 * @param defaultSupplier supplies a default value at an index. 837 * @return the object at the specified index 838 * @throws IndexOutOfBoundsException if the index is invalid 839 */ 840 static <E> E get(final Iterator<E> iterator, final int index, final IntFunction<E> defaultSupplier) { 841 int i = index; 842 CollectionUtils.checkIndexBounds(i); 843 while (iterator.hasNext()) { 844 i--; 845 if (i == -1) { 846 return iterator.next(); 847 } 848 iterator.next(); 849 } 850 return defaultSupplier.apply(i); 851 } 852 853 /** 854 * Gets a suitable Iterator for the given object. 855 * <p> 856 * This method can handle objects as follows 857 * </p> 858 * <ul> 859 * <li>null - empty iterator 860 * <li>Iterator - returned directly 861 * <li>Enumeration - wrapped 862 * <li>Collection - iterator from collection returned 863 * <li>Map - values iterator returned 864 * <li>Dictionary - values (elements) enumeration returned as iterator 865 * <li>array - iterator over array returned 866 * <li>object with iterator() public method accessed by reflection 867 * <li>object - singleton iterator 868 * <li>NodeList - iterator over the list 869 * <li>Node - iterator over the child nodes 870 * </ul> 871 * 872 * @param obj the object to convert to an iterator 873 * @return a suitable iterator, never null 874 */ 875 public static Iterator<?> getIterator(final Object obj) { 876 if (obj == null) { 877 return emptyIterator(); 878 } 879 if (obj instanceof Iterator) { 880 return (Iterator<?>) obj; 881 } 882 if (obj instanceof Iterable) { 883 return ((Iterable<?>) obj).iterator(); 884 } 885 if (obj instanceof Object[]) { 886 return new ObjectArrayIterator<>((Object[]) obj); 887 } 888 if (obj instanceof Enumeration) { 889 return new EnumerationIterator<>((Enumeration<?>) obj); 890 } 891 if (obj instanceof Map) { 892 return ((Map<?, ?>) obj).values().iterator(); 893 } 894 if (obj instanceof NodeList) { 895 return new NodeListIterator((NodeList) obj); 896 } 897 if (obj instanceof Node) { 898 return new NodeListIterator((Node) obj); 899 } 900 if (obj instanceof Dictionary) { 901 return new EnumerationIterator<>(((Dictionary<?, ?>) obj).elements()); 902 } 903 if (obj.getClass().isArray()) { 904 return new ArrayIterator<>(obj); 905 } 906 try { 907 final Method method = obj.getClass().getMethod("iterator", (Class[]) null); 908 if (Iterator.class.isAssignableFrom(method.getReturnType())) { 909 final Iterator<?> it = (Iterator<?>) method.invoke(obj, (Object[]) null); 910 if (it != null) { 911 return it; 912 } 913 } 914 } catch (final RuntimeException | ReflectiveOperationException ignore) { // NOPMD 915 // ignore 916 } 917 return singletonIterator(obj); 918 } 919 920 /** 921 * Returns the index of the first element in the specified iterator that 922 * matches the given predicate. 923 * <p> 924 * A {@code null} or empty iterator returns -1. 925 * </p> 926 * 927 * @param <E> the element type 928 * @param iterator the iterator to search, may be null 929 * @param predicate the predicate to use, may not be null 930 * @return the index of the first element which matches the predicate or -1 if none matches 931 * @throws NullPointerException if predicate is null 932 * @since 4.1 933 */ 934 public static <E> int indexOf(final Iterator<E> iterator, final Predicate<? super E> predicate) { 935 Objects.requireNonNull(predicate, "predicate"); 936 937 if (iterator != null) { 938 for (int index = 0; iterator.hasNext(); index++) { 939 final E element = iterator.next(); 940 if (predicate.test(element)) { 941 return index; 942 } 943 } 944 } 945 return CollectionUtils.INDEX_NOT_FOUND; 946 } 947 948 /** 949 * Checks if the given iterator is empty. 950 * <p> 951 * A {@code null} or empty iterator returns true. 952 * </p> 953 * 954 * @param iterator the {@link Iterator} to use, may be null 955 * @return true if the iterator is exhausted or null, false otherwise 956 * @since 4.1 957 */ 958 public static boolean isEmpty(final Iterator<?> iterator) { 959 return iterator == null || !iterator.hasNext(); 960 } 961 962 /** 963 * Gets an iterator that loops continuously over the supplied collection. 964 * <p> 965 * The iterator will only stop looping if the remove method is called 966 * enough times to empty the collection, or if the collection is empty 967 * to start with. 968 * </p> 969 * 970 * @param <E> the element type 971 * @param collection the collection to iterate over, not null 972 * @return a new looping iterator 973 * @throws NullPointerException if the collection is null 974 */ 975 public static <E> ResettableIterator<E> loopingIterator(final Collection<? extends E> collection) { 976 return new LoopingIterator<>(Objects.requireNonNull(collection, "collection")); 977 } 978 979 /** 980 * Gets an iterator that loops continuously over the supplied list. 981 * <p> 982 * The iterator will only stop looping if the remove method is called 983 * enough times to empty the list, or if the list is empty to start with. 984 * </p> 985 * 986 * @param <E> the element type 987 * @param list the list to iterate over, not null 988 * @return a new looping iterator 989 * @throws NullPointerException if the list is null 990 * @since 3.2 991 */ 992 public static <E> ResettableListIterator<E> loopingListIterator(final List<E> list) { 993 return new LoopingListIterator<>(Objects.requireNonNull(list, "list")); 994 } 995 996 /** 997 * Answers true if a predicate is true for every element of an iterator. 998 * <p> 999 * A {@code null} or empty iterator returns true. 1000 * </p> 1001 * 1002 * @param <E> the type of object the {@link Iterator} contains 1003 * @param iterator the {@link Iterator} to use, may be null 1004 * @param predicate the predicate to use, may not be null 1005 * @return true if every element of the collection matches the predicate or if the 1006 * collection is empty, false otherwise 1007 * @throws NullPointerException if predicate is null 1008 * @since 4.1 1009 */ 1010 public static <E> boolean matchesAll(final Iterator<E> iterator, final Predicate<? super E> predicate) { 1011 Objects.requireNonNull(predicate, "predicate"); 1012 1013 if (iterator != null) { 1014 while (iterator.hasNext()) { 1015 final E element = iterator.next(); 1016 if (!predicate.test(element)) { 1017 return false; 1018 } 1019 } 1020 } 1021 return true; 1022 } 1023 1024 /** 1025 * Answers true if a predicate is true for any element of the iterator. 1026 * <p> 1027 * A {@code null} or empty iterator returns false. 1028 * </p> 1029 * 1030 * @param <E> the type of object the {@link Iterator} contains 1031 * @param iterator the {@link Iterator} to use, may be null 1032 * @param predicate the predicate to use, may not be null 1033 * @return true if any element of the collection matches the predicate, false otherwise 1034 * @throws NullPointerException if predicate is null 1035 * @since 4.1 1036 */ 1037 public static <E> boolean matchesAny(final Iterator<E> iterator, final Predicate<? super E> predicate) { 1038 return indexOf(iterator, predicate) != -1; 1039 } 1040 1041 /** 1042 * Gets an {@link Iterator} that wraps the specified node's childNodes. 1043 * The returned {@link Iterator} can be used for a single iteration. 1044 * <p> 1045 * Convenience method, allows easy iteration over NodeLists: 1046 * </p> 1047 * <pre> 1048 * Iterator<Node> iterator = IteratorUtils.nodeListIterator(node); 1049 * for (Node childNode : IteratorUtils.asIterable(iterator)) { 1050 * ... 1051 * } 1052 * </pre> 1053 * 1054 * @param node the node to use, may not be null 1055 * @return a new, single use {@link Iterator} 1056 * @throws NullPointerException if node is null 1057 * @since 4.0 1058 */ 1059 public static NodeListIterator nodeListIterator(final Node node) { 1060 return new NodeListIterator(Objects.requireNonNull(node, "node")); 1061 } 1062 1063 /** 1064 * Gets an {@link Iterator} that wraps the specified {@link NodeList}. 1065 * The returned {@link Iterator} can be used for a single iteration. 1066 * 1067 * @param nodeList the node list to use, may not be null 1068 * @return a new, single use {@link Iterator} 1069 * @throws NullPointerException if nodeList is null 1070 * @since 4.0 1071 */ 1072 public static NodeListIterator nodeListIterator(final NodeList nodeList) { 1073 return new NodeListIterator(Objects.requireNonNull(nodeList, "nodeList")); 1074 } 1075 1076 /** 1077 * Gets an iterator that operates over an object graph. 1078 * <p> 1079 * This iterator can extract multiple objects from a complex tree-like object graph. 1080 * The iteration starts from a single root object. 1081 * It uses a {@code Transformer} to extract the iterators and elements. 1082 * Its main benefit is that no intermediate {@code List} is created. 1083 * </p> 1084 * <p> 1085 * For example, consider an object graph: 1086 * </p> 1087 * <pre> 1088 * |- Branch -- Leaf 1089 * | \- Leaf 1090 * |- Tree | /- Leaf 1091 * | |- Branch -- Leaf 1092 * Forest | \- Leaf 1093 * | |- Branch -- Leaf 1094 * | | \- Leaf 1095 * |- Tree | /- Leaf 1096 * |- Branch -- Leaf 1097 * |- Branch -- Leaf</pre> 1098 * <p> 1099 * The following {@code Transformer}, used in this class, will extract all 1100 * the Leaf objects without creating a combined intermediate list: 1101 * </p> 1102 * <pre> 1103 * public Object transform(Object input) { 1104 * if (input instanceof Forest) { 1105 * return ((Forest) input).treeIterator(); 1106 * } 1107 * if (input instanceof Tree) { 1108 * return ((Tree) input).branchIterator(); 1109 * } 1110 * if (input instanceof Branch) { 1111 * return ((Branch) input).leafIterator(); 1112 * } 1113 * if (input instanceof Leaf) { 1114 * return input; 1115 * } 1116 * throw new ClassCastException(); 1117 * }</pre> 1118 * <p> 1119 * Internally, iteration starts from the root object. When next is called, 1120 * the transformer is called to examine the object. The transformer will return 1121 * either an iterator or an object. If the object is an Iterator, the next element 1122 * from that iterator is obtained and the process repeats. If the element is an object 1123 * it is returned. 1124 * </p> 1125 * <p> 1126 * Under many circumstances, linking Iterators together in this manner is 1127 * more efficient (and convenient) than using nested for loops to extract a list. 1128 * </p> 1129 * 1130 * @param <E> the element type 1131 * @param root the root object to start iterating from, null results in an empty iterator 1132 * @param transformer the transformer to use, see above, null uses no effect transformer 1133 * @return a new object graph iterator 1134 * @since 3.1 1135 */ 1136 public static <E> Iterator<E> objectGraphIterator(final E root, 1137 final Transformer<? super E, ? extends E> transformer) { 1138 return new ObjectGraphIterator<>(root, transformer); 1139 } 1140 1141 /** 1142 * Gets an iterator that supports one-element lookahead. 1143 * 1144 * @param <E> the element type 1145 * @param iterator the iterator to decorate, not null 1146 * @return a peeking iterator 1147 * @throws NullPointerException if the iterator is null 1148 * @since 4.0 1149 */ 1150 public static <E> Iterator<E> peekingIterator(final Iterator<? extends E> iterator) { 1151 return PeekingIterator.peekingIterator(iterator); 1152 } 1153 1154 /** 1155 * Gets an iterator that supports pushback of elements. 1156 * 1157 * @param <E> the element type 1158 * @param iterator the iterator to decorate, not null 1159 * @return a pushback iterator 1160 * @throws NullPointerException if the iterator is null 1161 * @since 4.0 1162 */ 1163 public static <E> Iterator<E> pushbackIterator(final Iterator<? extends E> iterator) { 1164 return PushbackIterator.pushbackIterator(iterator); 1165 } 1166 1167 /** 1168 * Gets a singleton iterator. 1169 * <p> 1170 * This iterator is a valid iterator object that will iterate over 1171 * the specified object. 1172 * </p> 1173 * 1174 * @param <E> the element type 1175 * @param object the single object over which to iterate 1176 * @return a singleton iterator over the object 1177 */ 1178 public static <E> ResettableIterator<E> singletonIterator(final E object) { 1179 return new SingletonIterator<>(object); 1180 } 1181 1182 /** 1183 * Gets a singleton list iterator. 1184 * <p> 1185 * This iterator is a valid list iterator object that will iterate over 1186 * the specified object. 1187 * </p> 1188 * 1189 * @param <E> the element type 1190 * @param object the single object over which to iterate 1191 * @return a singleton list iterator over the object 1192 */ 1193 public static <E> ListIterator<E> singletonListIterator(final E object) { 1194 return new SingletonListIterator<>(object); 1195 } 1196 1197 /** 1198 * Returns the number of elements contained in the given iterator. 1199 * <p> 1200 * A {@code null} or empty iterator returns {@code 0}. 1201 * </p> 1202 * 1203 * @param iterator the iterator to check, may be null 1204 * @return the number of elements contained in the iterator 1205 * @since 4.1 1206 */ 1207 public static int size(final Iterator<?> iterator) { 1208 int size = 0; 1209 if (iterator != null) { 1210 while (iterator.hasNext()) { 1211 iterator.next(); 1212 size++; 1213 } 1214 } 1215 return size; 1216 } 1217 1218 /** 1219 * Decorates the specified iterator to skip the first N elements. 1220 * 1221 * @param <E> the element type 1222 * @param iterator the iterator to decorate 1223 * @param offset the first number of elements to skip 1224 * @return a new skipping iterator 1225 * @throws NullPointerException if the iterator is null 1226 * @throws IllegalArgumentException if offset is negative 1227 * @since 4.1 1228 */ 1229 public static <E> SkippingIterator<E> skippingIterator(final Iterator<E> iterator, final long offset) { 1230 return new SkippingIterator<>(iterator, offset); 1231 } 1232 1233 /** 1234 * Creates a stream on the given Iterable. 1235 * 1236 * @param <E> the type of elements in the Iterable. 1237 * @param iterable the Iterable to stream or null. 1238 * @return a new Stream or {@link Stream#empty()} if the Iterable is null. 1239 * @since 4.5.0-M3 1240 */ 1241 public static <E> Stream<E> stream(final Iterable<E> iterable) { 1242 return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false); 1243 } 1244 1245 /** 1246 * Creates a stream on the given Iterator. 1247 * 1248 * @param <E> the type of elements in the Iterator. 1249 * @param iterator the Iterator to stream or null. 1250 * @return a new Stream or {@link Stream#empty()} if the Iterator is null. 1251 * @since 4.5.0-M3 1252 */ 1253 public static <E> Stream<E> stream(final Iterator<E> iterator) { 1254 return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); 1255 } 1256 1257 /** 1258 * Gets an array based on an iterator. 1259 * <p> 1260 * As the wrapped Iterator is traversed, an ArrayList of its values is 1261 * created. At the end, this is converted to an array. 1262 * </p> 1263 * 1264 * @param iterator the iterator to use, not null 1265 * @return an array of the iterator contents 1266 * @throws NullPointerException if iterator parameter is null 1267 */ 1268 public static Object[] toArray(final Iterator<?> iterator) { 1269 Objects.requireNonNull(iterator, "iterator"); 1270 final List<?> list = toList(iterator, 100); 1271 return list.toArray(); 1272 } 1273 1274 /** 1275 * Gets an array based on an iterator. 1276 * <p> 1277 * As the wrapped Iterator is traversed, an ArrayList of its values is 1278 * created. At the end, this is converted to an array. 1279 * </p> 1280 * 1281 * @param <E> the element type 1282 * @param iterator the iterator to use, not null 1283 * @param arrayClass the class of array to create 1284 * @return an array of the iterator contents 1285 * @throws NullPointerException if iterator parameter or arrayClass is null 1286 * @throws ArrayStoreException if the arrayClass is invalid 1287 */ 1288 public static <E> E[] toArray(final Iterator<? extends E> iterator, final Class<E> arrayClass) { 1289 Objects.requireNonNull(iterator, "iterator"); 1290 Objects.requireNonNull(arrayClass, "arrayClass"); 1291 final List<E> list = toList(iterator, 100); 1292 @SuppressWarnings("unchecked") 1293 final E[] array = (E[]) Array.newInstance(arrayClass, list.size()); 1294 return list.toArray(array); 1295 } 1296 1297 /** 1298 * Gets a list based on an iterator. 1299 * <p> 1300 * As the wrapped Iterator is traversed, an ArrayList of its values is 1301 * created. At the end, the list is returned. 1302 * </p> 1303 * 1304 * @param <E> the element type 1305 * @param iterator the iterator to use, not null 1306 * @return a list of the iterator contents 1307 * @throws NullPointerException if iterator parameter is null 1308 */ 1309 public static <E> List<E> toList(final Iterator<? extends E> iterator) { 1310 return toList(iterator, 10); 1311 } 1312 1313 /** 1314 * Gets a list based on an iterator. 1315 * <p> 1316 * As the wrapped Iterator is traversed, an ArrayList of its values is 1317 * created. At the end, the list is returned. 1318 * </p> 1319 * 1320 * @param <E> the element type 1321 * @param iterator the iterator to use, not null 1322 * @param estimatedSize the initial size of the ArrayList 1323 * @return a list of the iterator contents 1324 * @throws NullPointerException if iterator parameter is null 1325 * @throws IllegalArgumentException if the size is less than 1 1326 */ 1327 public static <E> List<E> toList(final Iterator<? extends E> iterator, final int estimatedSize) { 1328 Objects.requireNonNull(iterator, "iterator"); 1329 if (estimatedSize < 1) { 1330 throw new IllegalArgumentException("Estimated size must be greater than 0"); 1331 } 1332 final List<E> list = new ArrayList<>(estimatedSize); 1333 while (iterator.hasNext()) { 1334 list.add(iterator.next()); 1335 } 1336 return list; 1337 } 1338 1339 /** 1340 * Gets a list iterator based on a simple iterator. 1341 * <p> 1342 * As the wrapped Iterator is traversed, a LinkedList of its values is 1343 * cached, permitting all required operations of ListIterator. 1344 * </p> 1345 * 1346 * @param <E> the element type 1347 * @param iterator the iterator to use, may not be null 1348 * @return a new iterator 1349 * @throws NullPointerException if iterator parameter is null 1350 */ 1351 public static <E> ListIterator<E> toListIterator(final Iterator<? extends E> iterator) { 1352 Objects.requireNonNull(iterator, "iterator"); 1353 return new ListIteratorWrapper<>(iterator); 1354 } 1355 1356 /** 1357 * Returns a string representation of the elements of the specified iterator. 1358 * <p> 1359 * The string representation consists of a list of the iterator's elements, 1360 * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated 1361 * by the characters {@code ", "} (a comma followed by a space). Elements are 1362 * converted to strings as by {@code String.valueOf(Object)}. 1363 * </p> 1364 * 1365 * @param <E> the element type 1366 * @param iterator the iterator to convert to a string, may be null 1367 * @return a string representation of {@code iterator} 1368 * @since 4.1 1369 */ 1370 public static <E> String toString(final Iterator<E> iterator) { 1371 return toString(iterator, TransformerUtils.stringValueTransformer(), 1372 DEFAULT_TOSTRING_DELIMITER, CollectionUtils.DEFAULT_TOSTRING_PREFIX, 1373 CollectionUtils.DEFAULT_TOSTRING_SUFFIX); 1374 } 1375 1376 /** 1377 * Returns a string representation of the elements of the specified iterator. 1378 * <p> 1379 * The string representation consists of a list of the iterable's elements, 1380 * enclosed in square brackets ({@code "[]"}). Adjacent elements are separated 1381 * by the characters {@code ", "} (a comma followed by a space). Elements are 1382 * converted to strings as by using the provided {@code transformer}. 1383 * </p> 1384 * 1385 * @param <E> the element type 1386 * @param iterator the iterator to convert to a string, may be null 1387 * @param transformer the transformer used to get a string representation of an element 1388 * @return a string representation of {@code iterator} 1389 * @throws NullPointerException if {@code transformer} is null 1390 * @since 4.1 1391 */ 1392 public static <E> String toString(final Iterator<E> iterator, 1393 final Transformer<? super E, String> transformer) { 1394 return toString(iterator, transformer, DEFAULT_TOSTRING_DELIMITER, 1395 CollectionUtils.DEFAULT_TOSTRING_PREFIX, CollectionUtils.DEFAULT_TOSTRING_SUFFIX); 1396 } 1397 1398 /** 1399 * Returns a string representation of the elements of the specified iterator. 1400 * <p> 1401 * The string representation consists of a list of the iterator's elements, 1402 * enclosed by the provided {@code prefix} and {@code suffix}. Adjacent elements 1403 * are separated by the provided {@code delimiter}. Elements are converted to 1404 * strings as by using the provided {@code transformer}. 1405 * </p> 1406 * 1407 * @param <E> the element type 1408 * @param iterator the iterator to convert to a string, may be null 1409 * @param transformer the transformer used to get a string representation of an element 1410 * @param delimiter the string to delimit elements 1411 * @param prefix the prefix, prepended to the string representation 1412 * @param suffix the suffix, appended to the string representation 1413 * @return a string representation of {@code iterator} 1414 * @throws NullPointerException if either transformer, delimiter, prefix or suffix is null 1415 * @since 4.1 1416 */ 1417 public static <E> String toString(final Iterator<E> iterator, 1418 final Transformer<? super E, String> transformer, 1419 final String delimiter, 1420 final String prefix, 1421 final String suffix) { 1422 Objects.requireNonNull(transformer, "transformer"); 1423 Objects.requireNonNull(delimiter, "delimiter"); 1424 Objects.requireNonNull(prefix, "prefix"); 1425 Objects.requireNonNull(suffix, "suffix"); 1426 final StringBuilder stringBuilder = new StringBuilder(prefix); 1427 if (iterator != null) { 1428 while (iterator.hasNext()) { 1429 final E element = iterator.next(); 1430 stringBuilder.append(transformer.apply(element)); 1431 stringBuilder.append(delimiter); 1432 } 1433 if (stringBuilder.length() > prefix.length()) { 1434 stringBuilder.setLength(stringBuilder.length() - delimiter.length()); 1435 } 1436 } 1437 stringBuilder.append(suffix); 1438 return stringBuilder.toString(); 1439 } 1440 1441 /** 1442 * Gets an iterator that transforms the elements of another iterator. 1443 * <p> 1444 * The transformation occurs during the next() method and the underlying 1445 * iterator is unaffected by the transformation. 1446 * </p> 1447 * 1448 * @param <I> the input type 1449 * @param <O> the output type 1450 * @param iterator the iterator to use, not null 1451 * @param transformer the transform to use, not null 1452 * @return a new transforming iterator 1453 * @throws NullPointerException if either parameter is null 1454 */ 1455 public static <I, O> Iterator<O> transformedIterator(final Iterator<? extends I> iterator, 1456 final Transformer<? super I, ? extends O> transformer) { 1457 1458 Objects.requireNonNull(iterator, "iterator"); 1459 Objects.requireNonNull(transformer, "transformer"); 1460 return new TransformIterator<>(iterator, transformer); 1461 } 1462 1463 /** 1464 * Gets an immutable version of an {@link Iterator}. The returned object 1465 * will always throw an {@link UnsupportedOperationException} for 1466 * the {@link Iterator#remove} method. 1467 * 1468 * @param <E> the element type 1469 * @param iterator the iterator to make immutable 1470 * @return an immutable version of the iterator 1471 */ 1472 public static <E> Iterator<E> unmodifiableIterator(final Iterator<E> iterator) { 1473 return UnmodifiableIterator.unmodifiableIterator(iterator); 1474 } 1475 1476 /** 1477 * Gets an immutable version of a {@link ListIterator}. The returned object 1478 * will always throw an {@link UnsupportedOperationException} for 1479 * the {@link Iterator#remove}, {@link ListIterator#add} and 1480 * {@link ListIterator#set} methods. 1481 * 1482 * @param <E> the element type 1483 * @param listIterator the iterator to make immutable 1484 * @return an immutable version of the iterator 1485 */ 1486 public static <E> ListIterator<E> unmodifiableListIterator(final ListIterator<E> listIterator) { 1487 return UnmodifiableListIterator.unmodifiableListIterator(listIterator); 1488 } 1489 1490 /** 1491 * Gets an immutable version of a {@link MapIterator}. The returned object 1492 * will always throw an {@link UnsupportedOperationException} for 1493 * the {@link Iterator#remove}, {@link MapIterator#setValue(Object)} methods. 1494 * 1495 * @param <K> the key type 1496 * @param <V> the value type 1497 * @param mapIterator the iterator to make immutable 1498 * @return an immutable version of the iterator 1499 */ 1500 public static <K, V> MapIterator<K, V> unmodifiableMapIterator(final MapIterator<K, V> mapIterator) { 1501 return UnmodifiableMapIterator.unmodifiableMapIterator(mapIterator); 1502 } 1503 1504 /** 1505 * Returns an iterator that interleaves elements from the decorated iterators. 1506 * 1507 * @param <E> the element type 1508 * @param iterators the array of iterators to interleave 1509 * @return an iterator, interleaving the decorated iterators 1510 * @throws NullPointerException if any iterator is null 1511 * @since 4.1 1512 */ 1513 public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E>... iterators) { 1514 return new ZippingIterator<>(iterators); 1515 } 1516 1517 /** 1518 * Returns an iterator that interleaves elements from the decorated iterators. 1519 * 1520 * @param <E> the element type 1521 * @param a the first iterator to interleave 1522 * @param b the second iterator to interleave 1523 * @return an iterator, interleaving the decorated iterators 1524 * @throws NullPointerException if any iterator is null 1525 * @since 4.1 1526 */ 1527 public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a, 1528 final Iterator<? extends E> b) { 1529 return new ZippingIterator<>(a, b); 1530 } 1531 1532 /** 1533 * Returns an iterator that interleaves elements from the decorated iterators. 1534 * 1535 * @param <E> the element type 1536 * @param a the first iterator to interleave 1537 * @param b the second iterator to interleave 1538 * @param c the third iterator to interleave 1539 * @return an iterator, interleaving the decorated iterators 1540 * @throws NullPointerException if any iterator is null 1541 * @since 4.1 1542 */ 1543 public static <E> ZippingIterator<E> zippingIterator(final Iterator<? extends E> a, 1544 final Iterator<? extends E> b, 1545 final Iterator<? extends E> c) { 1546 return new ZippingIterator<>(a, b, c); 1547 } 1548 1549 /** 1550 * Don't allow instances. 1551 */ 1552 private IteratorUtils() { 1553 // empty 1554 } 1555 1556 }