import java.util.*;
import java.util.stream.*;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<>();
al.add(7);
al.add(18);
al.add(10);
al.add(24);
al.add(17);
al.add(5);
System.out.println("Actual List: " + al);
Stream<Integer> stm = al.stream(); // get a stream; factory method
Optional<Integer> least = stm.min(Integer::compare); // Integer class implements Comparator [compare(obj1, obj2) static method]
if(least.isPresent())
System.out.println("Minimum integer: " + least.get());
// min is a terminal operation, get the stream again
/*
Optional<T> is a generic class packaged in java.util package.
An Optional class instance can either contains a value of type T or is empty.
Use method isPresent() to check if a value is present. Obtain the value by calling get()
*/
stm = al.stream();
System.out.println("Available values: " + stm.count());
stm = al.stream();
Optional<Integer> higher = stm.max(Integer::compare);
if(higher.isPresent())
System.out.println("Maximum integer: " + higher.get());
// max is a terminal operation, get stream again
Stream<Integer> sortedStm = al.stream().sorted(); // sorted() is intermediate operation
// here, we obtain a sorted stream
System.out.print("Sorted stream: ");
sortedStm.forEach(n -> System.out.print(n + " ")); // lambda expression
System.out.println();
/*
Consumer<T> is a generic functional interface declared in java.util.function
Its abstract method is: void accept(T obj)
The lambda expression in the call to forEach() provides the implementation of accept() method.
*/
Stream<Integer> odds = al.stream().sorted().filter(n -> (n % 2) == 1);
System.out.print("Odd values only: ");
odds.forEach(n -> System.out.print(n + " "));
System.out.println();
/*
Predicate<T> is a generic functional interface defined in java.util.function
and its abstract method is test(): boolean test(T obj)
Returns true if object for test() satisfies the predicate and false otherwise.
The lambda expression passed to the filter() implements this method.
*/
odds = al.stream().sorted().filter(n -> (n % 2) == 1).filter(n -> n > 5); // possible to chain the filters
System.out.print("Odd values bigger than 5 only: ");
odds.forEach(n -> System.out.print(n + " "));
System.out.println();
}
}