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