stream terminal operation in Java

<b>Terminal stream operations</b>
Method | What Happens for Infinite Streams | Return Value | Reduction
----- | ----- | ----- | -----
anyMatch()<br>allMatch()<br>noneMatch() | Sometimes terminates | boolean | No
collect() | Does not terminate | Varied | Yes
count() | Does not terminate | long | Yes
findAny()<br>findFirst() | Terminates | Optional<T> | No
forEach() | Does not terminate | void | No
min()/max() | Does not terminate | Optional<T> | Yes
reduce() | Does not terminate | Varied | Yes
toArray() | Does not terminate | Objects | No

* match
    * anyMatch(): it takes a predicate as parameter, starts the iteration of the stream, and applies the predicate to each element. If the predicate returns true for any of the elements, returns true. If no elements match the predicate, returns false. 
    * allMatch(): it takes a predicate as parameter, starts the iteration of the stream, and applies the predicate to each element. If the predicate returns true for all elements, returns true. If not, returns false.
    * noneMatch(): it takes a predicate as parameter, starts the iteration of the stream, and applies the predicate to each element. If the predicate returns false for all elements, returns true. If not, returns false.
```
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        System.out.println(Stream.of(1,2,3,4).anyMatch(i->{return i>=4;}));
        System.out.println(Stream.of(1,2,3,4).allMatch(i->{return i>=4;}));
        System.out.println(Stream.of(1,2,3,4).noneMatch(i->{return i>=4;}));
    }
}
```
* collect(): the collect() starts the iteration, and collects the elements in the stream in a collection or object of some kind. 
```
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        System.out.println(Stream.of(1,2,3,4).filter(i->i>2).collect(Collectors.toList()));
    }
}
```
* count(): the count() starts the iteration of the elements in the stream, and counts the elements.
```
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        System.out.println(Stream.of(1,2,3,4).filter(i->i>2).count());
    }
}
```
* find
    * findAny(): it finds a single element from anywhere in the Stream. There is no guarantee about from where in the stream the element is taken.
    * findFirst(): it finds the first element in the stream, if any elements are present. It returns an optional from which you can obtain the element, if present. 
```
import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        Optional<Integer> any = Stream.of(1,2,3,4).findAny();
        System.out.println(any.get());
        Optional<Integer> first = Stream.of(1,2,3,4).findFirst();
        System.out.println(first.get());
    }
}
```
* forEach(): it starts the iteration of the elements in the stream, and applies a consumer to each element. It returns void. 
```
import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        Stream.of(1,2,3,4).forEach(System.out::println);
    }
}
```
* min()/max(): The min()/max() method returns the smallest/biggest element in the stream. Which element is the smallest/biggest is determined by the comparator you pass to the min()/max() method. 
```
import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        Optional<Integer> min = Stream.of(1,2,3,4).min((i, j)->i.compareTo(j));
        System.out.println(min.get());    
        Optional<Integer> max = Stream.of(1,2,3,4).max((i, j)->i.compareTo(j));
        System.out.println(max.get());    
    }
}
```
* reduce(): The reduce() method reduces all elements in the stream to a single element. 
```
import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        Optional<Integer> reduced = Stream.of(1,2,3,4).reduce((v, cv)->{return cv+v;});
        System.out.println(reduced.get());
    }
}
```
* toArray(): The toArray() starts the iteration of the elements in the stream, and returns an array of Object containing all the elements.
```
import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        Object[] o = Stream.of(1,2,3,4).toArray();
        for(Object i:o)
            System.out.println(i);
    }
}
```