
// IteratorsTester.java
// https://www.demo2s.com/java/apache-commons-filteriterator-tutorial-with-examples.html
// Andrew Davison, ad@coe.psu.ac.th, May 2023

/* IteratorUtils and IterableUtils examples using lists:
      * FilterIterator
      * chainedIterable
      * zippingIterable
      * transformedIterable
      * countMatches
      * frequency
      * find
      * FluentIterable

   Also see ListUtilsTester.java, CollectionUtilsTester.java 

  Usage:
    > compile IteratorsTester.java
    > run IteratorsTester
*/


import java.util.*;

import org.apache.commons.collections4.*;
import org.apache.commons.collections4.iterators.*;


public class IteratorsTester
{

  public static void main(String[] args)
  {
    List<String> list = Arrays.asList("a", "b", "c", "a", "c");
    System.out.println("list: " + list);

    System.out.println("Filter out a's:");
    Iterator<String> iter = 
         new FilterIterator<>(list.iterator(), s -> !s.equals("a"));
    IteratorUtils.forEach(iter, System.out::println);

    System.out.println("No. of a's: " +
                IterableUtils.frequency(list, "a"));

    // -------------------------------

    List<String> list1 = Arrays.asList("one", "two", "three");
    System.out.println("\nlist1: " + list1);

    List<String> list2 = Arrays.asList("A", "B", "C");
    System.out.println("list2: " + list2);

    System.out.println("Chained iterable of list1+list2:");
    for (String s: IterableUtils.chainedIterable(list1, list2))
      System.out.print(" " + s);
    System.out.println();

    System.out.println("Zipped iterable of list1+list2:");
    for (String s: IterableUtils.zippingIterable(list1, list2))
      System.out.print(" " + s);
    System.out.println();

    System.out.println("Transformed iterable (length) of list1:");
    for (int len: IterableUtils.transformedIterable(
                         list1, s -> s.length()))
      System.out.print(" " + len);
    System.out.println();

    // -----------------------------------

    List<Integer> nums = Arrays.asList(1, 12, 23, 4, 5, 6, 7);
    System.out.println("\nnums: " + nums);

    System.out.printf("Count elements > 5: %d\n",
          IterableUtils.countMatches(nums, n -> (n > 5)));

    Integer firstBigger = 
            IterableUtils.find(nums, n -> (n > 3));
    System.out.printf("Find first element > 3: %d\n", firstBigger);


    // -----------------------------------

    // manipulate Iterables in a fluent manner
    List<Integer> result = FluentIterable.of(nums).
            filter(n -> (n > 5)).limit(3).toList();
    System.out.println("\nFluent of nums; elem > 5; limit to 3: " + result);


  }  // end of main()

}  // end of IteratorsTester class
