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