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 map() method of Optional object?

The map method of the Optional class in Java is used to transform the value contained in the Optional. map allows you to apply a function on the value inside the Optional and returns an Optional that contains the result of the function.

Here is an example of how to use it:

package org.kodejava.util;

import java.util.Optional;

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

        // Create an Optional<String>
        Optional<String> optional = Optional.of("Hello");

        // Use map method to transform the contained value
        Optional<Integer> transformedOptional = optional.map(String::length);

        // Use ifPresent to print the result if the Optional is not empty
        transformedOptional.ifPresent(System.out::println);
    }
}

In this example, we start with an Optional<String> that contains the string “Hello”. We then use map to apply the String::length method on the contained string. This transforms the Optional<String> into an Optional<Integer>, where the integer is the length of the string.

Lastly, we use ifPresent to print the result. In this case, the integer 5 will be printed.

Here is another example, where map helps us to handle null values:

Optional<String> optional = Optional.ofNullable(null);

// If optional is not present, it will print "0"
System.out.println(optional.map(String::length).orElse(0));

In this case, trying to apply String::length on a null value would result in a NullPointerException. However, using map in combination with Optional, allows us to safely transform the value and even provide a default result (“0” in this case) if the Optional is empty. This makes handling null values more reliable and your code less error-prone.

How do I use flatMap() method of Optional object?

The flatMap method is a special method in the Optional class in Java, if a method returns an Optional, you can use flatMap to avoid nested Optional<Optional<T>> situations.

Here is an example:

package org.kodejava.util;

import java.util.Optional;

public class OptionalFlatMap {
    public static void main(String[] args) {
        Optional<String> nonEmptyGender = Optional.of("male");
        Optional<String> emptyGender = Optional.empty();

        System.out.println("Non-Empty Optional:: " + nonEmptyGender.flatMap(OptionalFlatMap::getGender));
        System.out.println("Empty Optional:: " + emptyGender.flatMap(OptionalFlatMap::getGender));
    }

    static Optional<String> getGender(String gender) {
        if (gender.equals("male")) {
            return Optional.of("Gender is male");
        } else if (gender.equals("female")) {
            return Optional.of("Gender is female");
        } else {
            return Optional.empty();
        }
    }
}

In this example, two Optional<String> objects are created: one with a value (nonEmptyGender) and one without a value (emptyGender).

The flatMap method is used to apply the method getGender to the value of each Optional<String> (if it exists). Since getGender returns an Optional<String>, using flatMap avoids creating Optional<Optional<String>> objects, and instead directly returns an Optional<String>, that we can easily consume.

The getGender method returns an Optional object, that describes the gender if it is “male” or “female”, or an empty Optional if the gender is neither “male” nor “female”.

The result of calling flatMap will hence be an Optional<String> describing the gender if the gender is “male” or “female”, or an empty Optional in all other cases. This applies to both the non-empty and the empty Optional<String> in the example.

The final output will be:

Non-Empty Optional:: Optional[Gender is male]
Empty Optional:: Optional.empty

In both cases, note that flatMap directly returns the result of getGender, which itself is an Optional. This is different from if map was used, which would have resulted in a nested Optional.

How do I use filter() method of Optional object?

The java.util.Optional class in Java provides a filter method. It’s used to apply a condition on the value held by this Optional.

Here is an example of how to use Optional‘s filter method:

package org.kodejava.util;

import java.util.Optional;

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

        // Creating Optional object and assigning a value
        Optional<String> myOptional = Optional.of("Hello");

        // Applying filter method on Optional
        Optional<String> result = myOptional.filter(value -> value.length() > 5);

        // Print the result
        // This will not print anything because the length of "Hello" 
        // is not greater than 5.
        result.ifPresent(System.out::println);
    }
}

In this example, the filter method is used to apply a condition on the value held by this myOptional object. The condition is that the length of the value should be greater than 5. If the value satisfies the condition, it is returned. Otherwise, an empty Optional object is returned.

The ifPresent method is used to print the value held by this Optional, if it is non-empty. This particular use of filter will not print anything because the string “Hello” length is not greater than 5.

You can use isEmpty method to check whether Optional is empty.

if (result.isEmpty()) {
   System.out.println("The Optional is empty");
}

In this case, it would print “The Optional is empty”.

How do I use java.util.Optional class?

The java.util.Optional<T> class is a container object that may or may not contain a non-null value. It was introduced in Java 8 as part of the Java language’s growing emphasis on treating null values as an anti-pattern. Optional is a way of replacing a nullable T reference with a non-null but potentially empty Optional<T> reference.

In functional terminology, Optional is a monadic sequence of operations that can be combined to work with data in a declarative way, while deferring some operations, such as computations on elements.

Here are some useful methods that Optional class provides:

  1. Optional.of(T value): Returns an Optional with the specified present non-null value.
  2. Optional.empty(): Returns an empty Optional instance.
  3. Optional.ofNullable(T value): Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
  4. get(): If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.
  5. isPresent(): Returns true if there is a value present, otherwise false.
  6. ifPresent(Consumer<? super T> consumer): If a value is present, invokes the specified consumer with the value, otherwise does nothing.
  7. orElse(T other): Returns the value if present, otherwise returns other.
  8. orElseGet(Supplier<? extends T> other): Returns the value if present, otherwise returns the result produced by the supplying function.
  9. orElseThrow(Supplier<? extends X> exceptionSupplier): If a value is present, returns the value, otherwise throws an exception produced by the exception supplying function.

In practical terms, using Optional can help make your code more robust and reduce the likelihood of NullPointerException.

Here is a simple example:

package org.kodejava.util;

import java.util.Optional;

public class OptionalIntroduction {
    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Hello, world!");
        if (opt.isPresent()) {
            System.out.println(opt.get());
        }
    }
}

This program will output: Hello, world!

We can utilize functional-style programming by using ifPresent() method provided by the Optional class. Here’s how:

package org.kodejava.util;

import java.util.Optional;

public class OptionalIfPresent {
    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Hello, world!");
        opt.ifPresent(System.out::println);
    }
}

In this example, opt.ifPresent(System.out::println); is used to print the value of opt if it is present. The System.out::println syntax is a method reference in Java 8 that is functionally equivalent to value -> System.out.println(value). It will only execute System.out.println() if opt is not empty. Hence, it can be considered functional-style programming.

Here are another code snippet on using other methods from the java.util.Optional class:

package org.kodejava.util;

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        // Creating Optional objects
        // 1. Creates an empty Optional
        Optional<String> empty = Optional.empty();
        // 2. Creates an Optional with a non-null value
        Optional<String> nonEmpty = Optional.of("Hello");
        // 3. Creates an Optional with a null value
        Optional<String> nullable = Optional.ofNullable(null);

        // isPresent()
        // 1. Output: true
        System.out.println(nonEmpty.isPresent());
        // 2. Output: false
        System.out.println(empty.isPresent());

        // ifPresent()
        // 1. Output: Value is present: Hello
        nonEmpty.ifPresent(value -> System.out.println("Value is present: " + value));
        // 2. No output, since the Optional is empty.
        empty.ifPresent(value -> System.out.println("Value is present: " + value));

        // orElse()
        String valueFromNonEmpty = nonEmpty.orElse("Default Value");
        String valueFromEmpty = empty.orElse("Default Value");
        // Output: Hello
        System.out.println(valueFromNonEmpty);
        // Output: Default Value
        System.out.println(valueFromEmpty);

        // orElseGet()
        String valueFromNonEmptyWithSupplier = nonEmpty.orElseGet(() -> "Default Value");
        String valueFromEmptyWithSupplier = empty.orElseGet(() -> "Default Value");
        // Output: Hello
        System.out.println(valueFromNonEmptyWithSupplier);
        // Output: Default Value
        System.out.println(valueFromEmptyWithSupplier);

        // orElseThrow() when value is present it will return the value
        try {
            String value = nonEmpty.orElseThrow(IllegalArgumentException::new);
            System.out.println(value);
        } catch (IllegalArgumentException e) {
            //Handle exception
            e.printStackTrace();
        }
        // orElseThrow() when value is not present, it throws an exception
        try {
            String value = empty.orElseThrow(IllegalArgumentException::new);
            System.out.println(value);
        } catch (IllegalArgumentException e) {
            //Handle exception
            e.printStackTrace();
        }

    }
}

Output:

true
false
Value is present: Hello
Hello
Default Value
Hello
Default Value
Hello
java.lang.IllegalArgumentException
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.kodejava.util.OptionalExample.main(OptionalExample.java:53)

These methods are used to help in providing a more elegant way to handle null values in Java. Make sure to understand how and when to use each method to get the most out of the Optional class.