Package: groovy.util

## [Java] Class Iterators

- groovy.util.Iterators

-     public class Iterators
      extends Object

  Provides some iterator based generators.

  Since:
    5.0.0

- - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `<K, T>` | `public static Iterator<Map<K, T>>` | `combine(Map<K, ? extends Iterator<T>> map)` An iterator returning a map for each combination of elements the iterator sources.
    `<K, T>` | `public static Iterator<Map<K, T>>` | `combine(Map<K, ? extends Iterator<T>> map, boolean fairOrdering)` An iterator returning a map for each combination of elements the iterator sources.
    `<T>` | `public static Iterator<T>` | `generate(Supplier<? extends T> next)` An iterator providing infinite elements using a Supplier.
    `<T>` | `public static Iterator<T>` | `iterate(T seed, UnaryOperator<T> advance)` An iterator providing infinite elements using a seed and a UnaryOperator to produce the next element from the previous one.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Method Detail

    - #### <K, T> public static Iterator<Map<K, T>> combine(Map<K, ? extends Iterator<T>> map)

      An iterator returning a map for each combination of elements the iterator sources. If one of the iterators is infinite, the produced elements will be infinite and will need to be appropriately handled. By necessity, elements from the iterators are cached, so you should use Iterables.combine if you have existing iterables as this will be more efficient.

           assert Iterators.combine(x: (1..2).iterator(), y: ('a'..'c').iterator()).collect().toString()
               == '[[x:1, y:a], [x:1, y:b], [x:1, y:c], [x:2, y:a], [x:2, y:b], [x:2, y:c]]'
           assert Iterators.combine(x: (1..3).iterator(), y: ('a'..'b').iterator()).collect().toString()
               == '[[x:1, y:a], [x:1, y:b], [x:2, y:a], [x:2, y:b], [x:3, y:a], [x:3, y:b]]'

      Parameters:
        `map` - the named source iterators
      Returns:
        the output iterator of named combinations

    - #### <K, T> public static Iterator<Map<K, T>> combine(Map<K, ? extends Iterator<T>> map, boolean fairOrdering)

      An iterator returning a map for each combination of elements the iterator sources. If one of the iterators is infinite, the produced elements will be infinite and will need to be appropriately handled. By necessity, elements from the iterators are cached, so you should use Iterables.combine if you have existing iterables as this will be more efficient.

           assert Iterators.combine(
               even: Iterators.iterate(0, n -> n + 2),
               odd: Iterators.iterate(1, n -> n + 2), false)
               .take(10).collect().join('\n')
               == '''
           [even:0, odd:1]
           [even:0, odd:3]
           [even:0, odd:5]
           [even:0, odd:7]
           [even:0, odd:9]
           [even:0, odd:11]
           [even:0, odd:13]
           [even:0, odd:15]
           [even:0, odd:17]
           [even:0, odd:19]
           '''.trim()

           assert Iterators.combine(
               even: Iterators.iterate(0, n -> n + 2),
               odd: Iterators.iterate(1, n -> n + 2), true)
               .take(10).collect().join('\n')
               == '''
           [even:0, odd:1]
           [even:0, odd:3]
           [even:2, odd:1]
           [even:2, odd:3]
           [even:0, odd:5]
           [even:2, odd:5]
           [even:4, odd:1]
           [even:4, odd:3]
           [even:4, odd:5]
           [even:0, odd:7]
           '''.trim()

      Parameters:
        `map` - the named source iterators
        `fairOrdering` - determine the ordering in which combinations are processed, fair implies that all source iterators will be visited roughly equally (until exhausted)
      Returns:
        the output iterator of named combinations

    - #### <T> public static Iterator<T> generate(Supplier<? extends T> next)

      An iterator providing infinite elements using a Supplier. Since the iterator produces infinite elements, you should have some means to stop requesting elements external to this iterator.

           import java.util.function.Supplier
           var r = new Random()
           assert Iterators.generate({ r.nextInt(10) } as Supplier).take(3).collect() ==~ /\[\d, \d, \d\]/

      Parameters:
        `next` - the supplier of elements
      See Also:
        Stream.generate
      Returns:
        the iterator of generated values

    - #### <T> public static Iterator<T> iterate(T seed, UnaryOperator<T> advance)

      An iterator providing infinite elements using a seed and a UnaryOperator to produce the next element from the previous one. Since the iterator produces infinite elements, you should have some means to stop requesting elements external to this iterator.

           assert Iterators.iterate(0, n -> n + 2).take(5).toList() == [0, 2, 4, 6, 8]
           assert Iterators.iterate('a', String::next).take(6).join() == 'abcdef'

      Parameters:
        `seed` - the first element
        `advance` - an operator returning the next element given the current (previous) one.
      See Also:
        Stream.iterate
      Returns:
        the iterator of produced elements