
// CollectionUtilsTester.java
// https://www.baeldung.com/apache-commons-collection-utils
// Andrew Davison, ad@coe.psu.ac.th, May 2023

/*  CollectionUtils examples using lists:
      * collate
      * collect
      * filter
      * isSubCollection
      * set ops: intersection, subtract, union

   Also see ListUtilsTester.java, IteratorsTester.java


  Usage:
    > compile CollectionUtilsTester.java
    > run CollectionUtilsTester
*/

import java.util.*;

import org.apache.commons.collections4.*;
import org.apache.commons.collections4.map.*;



public class CollectionUtilsTester
{

  public static void main(String[] args) 
  {
    Employee emp1 = new Employee("Daniel", "male", "USA");
    Employee emp2 = new Employee("Fredrik", "male", "USA");
    Employee emp3 = new Employee("Kath", "female", "UK");
    Employee emp4 = new Employee("Bob", "male", "UK");
    Employee emp5 = new Employee("Jane", "female", "Fra");
    Employee emp6 = new Employee("John", "male", "Fra");

    List<Employee> list1 = Arrays.asList(emp1, emp2, emp3);
    List<Employee> list1b = new LinkedList<>(list1);

    List<Employee> list2 = Arrays.asList(emp4, emp5, emp6);

    List<Employee> list3 = Arrays.asList(emp1, emp2);


    // -----------------------------------

    System.out.println("list1: " + list1);
    System.out.println("list2: " + list2);
    List<Employee> sortedList = CollectionUtils.collate(list1, list2);
    System.out.println("collate: " + sortedList);
    System.out.println("Size: " + sortedList.size());


    // -----------------------------------

    Collection<String> locs = CollectionUtils.collect(list1,
                                                emp -> emp.getCountry() );
    System.out.println("\nCountries from list1: " + locs);

    System.out.println("\nStrings -> ints");
    List<String> strs = Arrays.asList("   1","002","3");
    System.out.println("Strings list: " + strs);
    List<Integer> nums = (List<Integer>) 
           CollectionUtils.collect(strs, s -> Integer.parseInt(s.trim()));
    System.out.println("Nums version: " + nums);


    System.out.println("\nints -> Strings");
    nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    System.out.println("nums list: " + nums);
    Collection<String> numsStrs = 
       CollectionUtils.collect(nums, n -> String.format("n%d", n));
    System.out.println("To strings: " + numsStrs);


    // -----------------------------------

    System.out.println("\nFiltering list by names...");
    System.out.println("list1b: " + list1b);

    boolean isModified = CollectionUtils.filter(list1b,
         emp -> Arrays.asList("Daniel", "Kyle").contains(emp.getName()) );
    System.out.println("Was list modified? " + isModified + 
                             "; size: " + list1b.size());
    System.out.println("list1b: " + list1b);

    System.out.println("\nFiltering ints");
    List<Integer> mnums = new ArrayList<>(nums); // mutable copy
    System.out.println("List: " + mnums);
    CollectionUtils.filter(mnums, n -> (n % 2 == 0));
    System.out.println("Evens: " + mnums);


    // -----------------------------------

    System.out.println("\nlist1: " + list1);
    System.out.println("list3: " + list3);
    System.out.println("Is list3 a sub selection of list1? " + 
                 CollectionUtils.isSubCollection(list3, list1));

    // -----------------------------------

    Collection<Employee> intersection = 
                          CollectionUtils.intersection(list1, list3);
    System.out.println("\nintersection of 1 & 3: " + intersection);

    Collection<Employee> sub = CollectionUtils.subtract(list1, list3);
    System.out.println("\nsubtraction 1-3: " + sub);
    System.out.println("- Contains emp1? " + sub.contains(emp1));

    Collection<Employee> union = CollectionUtils.union(list1, list2);
    System.out.println("\nlist2: " + list2);
    System.out.println("union 1+2: " + union);
    System.out.println("- Contains " + emp1 + "? " + union.contains(emp1));


  } // end of main()

} // end of CollectionUtilsTester class