Module iu.util
Package edu.iu

Class IuIterable

java.lang.Object
edu.iu.IuIterable

public final class IuIterable extends Object
Lightweight factory, manipulation, and processing utility for constantly repeatable Iterable and other Supplier<Iterator> compatible iterator sources.

This utility is useful for low-level optimization routines. Note that:

 for (var reduced : IuIterable.map(myList, a::reducer)) {
        // do something with reduced
 }
 for (var filtered : IuIterable.filter(myList, a::matches)) {
        // do something with reduced
 }
 

...are equivalent to:

 myList.stream().map(a::reducerMethod)...// do something
 myList.stream().filter(a::isMatching)...// do something
 

...but with minimal object creation (w/o Stream overhead), and in a form that may be used directly in a for loop.

IuIterable factory instances are recommended for all potentially temporary or synchronized complex constantly repeatable iteration scenarios, as in the examples above. This consideration improves reachability, i.e., by unit tests and debug breakpoints, compared to Iterable.forEach(Consumer).

Factory iterables are also preferred over Stream forms.

In particular, cat(Iterable...) is useful for union joins of like iterations.:

 for (var item : IuIterable.cat(myCollection, iter(myArray), myMap.values())) {
        // do something with items
 }
 

A common case for constantly repeatable iteration is returning a value from or passing an argument to a method on a business interface.

Factory iterators implement Object.hashCode() by returning the number of items already removed from the head of the iterator, and Object.equals(Object) for non-destructively comparing the tail end to that of another factory iterator. These semantics may be used reliably for short-term set operations between concurrent iterators.

API Note: Constantly repeatable refers to an immutable Iterator source factory backed by a fixed number of data elements strictly composed of primitive values and constable instances (i.e., java.time, Collection and Map with strictly constable values, etc). Source must be immutable—Iterator.remove() will not be invoked and should not be implemented. These conditions are not verifiable, so results are undefined if not met by the application.

All factory Iterable instances should be considered disposable and used only in local variable scope. Take care not to pass factory instances to lambdas, inline, or anonymous classes. Iterables backing these instances need only remain constantly repeatable while in use (i.e. backing a for loop). Once out of scope, the backing sources may change. Therefore, consumers should hold source references, not factory instances.

Since:
5.4
  • Method Details

    • of

      public static <T> Iterable<T> of(Supplier<Iterator<T>> supplier)
      Creates an Iterable instance from a constantly repeatable supplier.
      Type Parameters:
      T - item type
      Parameters:
      supplier - Iterable Supplier; must be constantly repeatable.
      Returns:
      Iterable
    • empty

      public static <T> Iterable<T> empty()
      Returns an Iterable that supplies empty Iterators.
      Type Parameters:
      T - item type
      Returns:
      empty Iterable
    • print

      public static String print(Iterable<?> iterable)
      Returns a string representation of an Iterable.
      Parameters:
      iterable - Iterable
      Returns:
      Object.toString() if iterable is a Collection, otherwise returns .toString(iterable.iterator())
    • print

      public static String print(Iterator<?> iterator)
      Returns a string representation of all remaining elements of an Iterator.
      Parameters:
      iterator - Iterator, will be exhausted
      Returns:
      string representation
    • print

      public static String print(Iterator<?> iterator, int skip) throws NoSuchElementException, IllegalArgumentException
      Returns a string representation of remaining elements of an Iterator, after skipping a specified number of elements.
      Parameters:
      iterator - Iterator, will be exhausted
      skip - number of steps to skip before recording; may be 0 to skip no steps. Skipped steps are printed as "..."
      Returns:
      string representation
      Throws:
      NoSuchElementException - if skip requests skipping elements no present on the source iterable.
      IllegalArgumentException - if skip < 0
    • remaindersAreEqual

      public static boolean remaindersAreEqual(Iterator<?> i1, Iterator<?> i2)
      Steps through two iterators, comparing all remaining items on each until either both are exhausted or items mismatch between the two.

      This is a destructive operation that renders both arguments unusable.

      Parameters:
      i1 - Iterator, will either be exhausted or left in an unknown state.
      i2 - Iterator, will either be exhausted or left in an unknown state.
      Returns:
      true if both iterators contained the same number of items, and all items in both iterators were Object.equals(Object) in the order iterated.
    • iter

      @SafeVarargs public static <T> Iterable<T> iter(T... a)
      Wraps an array.
      Type Parameters:
      T - item type
      Parameters:
      a - array
      Returns:
      An iterable over the entire array.
    • iter

      public static <T> Iterable<T> iter(T[] a, int from)
      Wraps an array.
      Type Parameters:
      T - item type
      Parameters:
      a - array
      from - starting point
      Returns:
      An iterable over the array starting from the point indicated.
    • cat

      @SafeVarargs public static <T> Iterable<T> cat(Iterable<T>... iterables)
      Concatenates one or more iterables.
      Type Parameters:
      T - item type
      Parameters:
      iterables - iterables
      Returns:
      A single iterable over all iterables in sequence.
    • map

      public static <T, U> Iterable<U> map(Iterable<T> i, Function<T,U> f)
      Maps an iterable using a transform function.
      Type Parameters:
      T - item type
      U - transformed item type
      Parameters:
      i - iterable
      f - transform function
      Returns:
      An iterable over the results of applying the transform function to the items available from the iterable.
    • select

      public static <T> T select(Iterable<T> i, Predicate<T> p)
      Selects the first Iterable element that matches a Predicate condition.
      Type Parameters:
      T - item type
      Parameters:
      i - iterable
      p - predicate
      Returns:
      The first element that meets the condition.
    • filter

      public static <T> Iterable<T> filter(Iterable<T> i, Predicate<T> p)
      Filters an Iterable using predicate.
      Type Parameters:
      T - item type
      Parameters:
      i - iterable
      p - predicate
      Returns:
      An iterable over the items for which the predicate returns true.
    • stream

      public static <T> Stream<T> stream(Iterable<T> i)
      Gets a Stream of the elements in an constantly repeatable Iterable.
      Type Parameters:
      T - element type
      Parameters:
      i - Iterable of elements
      Returns:
      Stream