import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.stream.IntStream;
import java.util.Optional;
import java.util.Arrays;

class Streams {
	public static void main(String[] args) {

		ArrayList<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(2);
		list.add(2);
		list.add(3);
		list.add(4);
		list.add(5);
		list.add(5);
		list.add(5);

		Stream<Integer> s1 = list.stream();
		long count = s1.count();
		System.out.println("s1 count: " + count);

		count = list.stream().count();
		System.out.println("s1 count: " + count);
	
		int[] arr = {1,2,3,3,5,5,5,4};
		IntStream s2 = Arrays.stream(arr);
		count = s2.count();
		System.out.println("s2 count: " + count);

		/* intermediate methods - return an instance
			of Stream, so we can chain them */

		// Stream<T> distinct()

		count = list.stream().distinct().count();
		System.out.println("s1 distinct count: " + count);
	
		// terminal method named forEach(Consumer<? super T> action)
		// void accept(T t)

		list.stream().distinct().forEach((elm) -> {
			System.out.println("elm: " + elm);
		});

		ArrayList<Integer> list2 = new ArrayList<>();
		list.stream().distinct().forEach((elm) -> list2.add(elm) );

		for(int i : list2) {
			System.out.println("list2: " + i);
		}	

		// Stream<T> filter(Predicate<? super T> pred)
		// boolean test(T t)

		list.stream().filter((elm) -> elm % 2 == 0)
			.forEach((elm) -> System.out.println("filtered: " + elm));

		Optional<Integer> opt = list.stream().distinct().min(Integer::compare);
		if(opt.isPresent()) {
			System.out.println("min: " + opt.get());
		}
			

	}
}
