## How do I use Collectors.maxBy() method?

The `Collectors.maxBy()` method is used to find the maximum element from a stream based on a certain comparator. It returns an `Optional` which contains the maximum element according to the provided comparator, or an empty `Optional` if there are no elements in the stream.

Here’s a simple example where we have a list of integers, and we want to find the biggest integer:

``````package org.kodejava.stream;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class MaxByDemo {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

Optional<Integer> maxNumber = numbers.stream()
.collect(Collectors.maxBy(Comparator.naturalOrder()));

maxNumber.ifPresent(System.out::println);
}
}
``````

In this example:

• We create a Stream from the list of integers.
• We then use `Collectors.maxBy(Comparator.naturalOrder())` to get the maximum number. `Comparator.naturalOrder()` is a shortcut for `Comparator.comparing(Function.identity())`.
• `Collectors.maxBy()` returns an `Optional` because the stream could be empty.
• We print the maximum number if it exists.

When you run this program, it will print “5” because 5 is the biggest number in the list.

Keep in mind that if the stream is empty, `maxNumber` will be an empty `Optional`, and nothing will be printed.

## How do I use Collectors.minBy() method?

The `Collectors.minBy()` method in Java 8 is used to find the minimum element from a stream of elements based on a certain comparator. It returns an `Optional` describing the minimum element of the stream, or an empty `Optional` if the stream is empty.

Here’s an example of how to use `Collectors.minBy()`. Assume we have a list of integers, and we want to find the smallest element.

``````package org.kodejava.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class CollectorsMinBy {
public static void main(String... args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

Optional<Integer> min = numbers.stream()
.collect(Collectors.minBy(Integer::compare));

min.ifPresent(System.out::println);
}
}
``````

In this code:

• We have a list of integers.
• We create a Stream from the list and collect the stream into an Optional that might hold the minimum value via the `Collectors.minBy(Integer::compare)` collector.
• `Integer::compare` is a method reference that is used to instruct `Collectors.minBy()` on how to compare the integers.
• `min.ifPresent(System.out::println)` checks if the `Optional` has a value. If it does, the value is passed to the `System.out::println` method and printed to the console.

When run, this program prints the smallest number in our list, which is “1”.

Note that if the list is empty, min will hold an empty `Optional`, and `min.ifPresent(System.out::println)` will not print anything.

Here’s another example of how you can use the `Collectors.minBy()` method to find the object containing the minimum value for a certain property. Let’s assume we have a `Person` class and a list of `Person` objects, and we want to find which `Person` has the smallest age.

``````package org.kodejava.stream;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class CollectorsMinByObjectProperty {
public static void main(String... args) {
List<Person> people = Arrays.asList(
new Person("Rosa", 21),
new Person("Bob", 25),
new Person("Alice", 18),
new Person("John", 22));

Optional<Person> youngestPerson = people.stream()
.collect(Collectors.minBy(Comparator.comparingInt(Person::getAge)));

youngestPerson.ifPresent(System.out::println);
}

static class Person {
String name;
int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}

public int getAge() {
return age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
``````

Output:

``````Person{name='Alice', age=18}
``````

In this code:

• The `Person` class has two fields, name and age, and a getter for the age field.
• We have a list of `Person` objects.
• We create a Stream from the list and then use `Collectors.minBy()` to find the `Person` with the smallest age. To do this, we use `Comparator.comparingInt(Person::getAge)`, which compares the `Person` objects based on their age.
• `Collectors.minBy()` returns an `Optional` that might hold the `Person` with the smallest age.
• If such a `Person` exists, we print that `Person` using `System.out::println`.

This program prints: `Person{name='Alice', age=18}`, as Alice is the person with the smallest age.

## How do I use Collectors.counting() method?

The `Collectors.counting()` method is a terminal operation that returns the count of elements in the particular stream where it is used. This is part of the `java.util.stream.Collectors` in Java 8.

Here is a simple example of how to use `Collectors.counting()`. Suppose we have a list of strings, and we want to count the number of elements in it.

``````package org.kodejava.stream;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectorsCounting {
public static void main(String... args) {
List<String> names = Arrays.asList("Rosa", "Bob", "Alice", "Dave", "John");

long count = names.stream()
.collect(Collectors.counting());

System.out.println("Count: " + count);
}
}
``````

Output:

``````Count: 5
``````

In this code:

• We have a list of names.
• We create a stream from this list using the `.stream()` method.
• We count the elements of the stream using `.collect(Collectors.counting())`, which returns the number of elements in the stream.
• Finally, we print the `count`.

When we run the program, we will get the output “Count: 5”, because there are five elements in the list.

The `Collectors.counting()` method is often used in conjunction with other methods like `Collectors.groupingBy()` to perform more complex operations like counting the number of elements in each group.

## How do I use Collectors.toCollection() method?

The `Collectors.toCollection()` method is a static method in the `java.util.stream.Collectors` class of Java 8. This method is used with streams when you want to convert a list to another collection type.

Here’s a simple example of how to use the method:

``````package org.kodejava.stream;

import java.util.*;
import java.util.stream.Collectors;

public class CollectorsToCollection {
public static void main(String[] args) {
List<String> list =
Arrays.asList("Java", "Kotlin", "Python", "Scala", "Kotlin");

// Convert List to TreeSet
TreeSet<String> treeSet = list.stream()
.collect(Collectors.toCollection(TreeSet::new));

System.out.println(treeSet);
}
}
``````

Output:

``````[Java, Kotlin, Python, Scala]
``````

In this code:

• We have a List of Strings.
• We convert this list into a `TreeSet`.
• `Collectors.toCollection(TreeSet::new)` is the collector that collects the data from the stream into a new `TreeSet`.
• The method referenced by `TreeSet::new` is a constructor reference that creates a new empty `TreeSet`.

The output of the program will be the `TreeSet` containing the elements of the list.

Keep in mind that a `TreeSet` automatically orders its elements (in this case, alphabetically since the elements are Strings) and does not allow duplicates. So, if the list had duplicate values, and you wanted to maintain them in your new collection, you would need to choose a different type of `Set` or use a `List`.

## How do I use Collectors.partitioningBy() method?

`Collectors.partitioningBy()` is a special case of a grouping collector in Java’s Stream API. It partitions or divides the input elements into two groups, based on the result of a `Predicate` function. One group for which the `Predicate` function returns `true`, and the other where it returns `false`.

Each group is a `List` of elements, and the method returns a `Map` where the keys are `Boolean` values (`true` and `false`), and the values are the resulting groups.

Here’s a simple example:

``````package org.kodejava.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class OddEvenNumberPartitioning {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

Map<Boolean, List<Integer>> isEven = numbers.stream()
.collect(Collectors.partitioningBy(num -> num % 2 == 0));

System.out.println("Partition of Even Numbers: " + isEven.get(true));
System.out.println("Partition of Odd Numbers: " + isEven.get(false));
}
}
``````

Output:

``````Partition of Even Numbers: [2, 4, 6, 8, 10]
Partition of Odd Numbers: [1, 3, 5, 7, 9]
``````

In this example, we’re partitioning a list of integers into even and odd numbers. The `Predicate` function `num -> num % 2 == 0` returns `true` for even numbers and `false` for odd numbers.

The value that `partitioningBy()` method returns is a `Map` where the key `true` maps to a list of numbers for which the `Predicate` was `true` (even numbers), and the key `false` maps to a list of numbers for which the `Predicate` was `false` (odd numbers).

You can use `partitioningBy()` to easily categorize elements of a stream where the categorization criterion can be represented with a boolean value (i.e., you have a binary condition to divide your elements).