Java BiConsumer Functional Interface Tutorial

Overview

The BiConsumer is a part of the java.util.function package. As the name suggest, this interface is a Consumer. That means it takes input arguments and returns void.

Practical use cases

This interface can be useful in various cases, for example, it can be used to create side effects like modifying state, printing, or logging.

BiConsumer Examples

BiConsumer<String, Integer> printKeyValue = (key, value) -> {
   System.out.println(key + ": " + value);
};

printKeyValue.accept("Alice", 1000);

Here, I created a BiConsumer and provided the implementation method to the abstract method named accept.

Using the consumer is quite straightforward:

Using BiConsumer in stream

Using the BiConsumer above, let’s see how you can use it in a stream:

    public static void main(String[] args) {

        BiConsumer<String, Integer> printKeyValue = (key, value) -> {
            System.out.println(key + ": " + value);
        };
        var cities = List.of("Hanoi", "New York", "Canberra");

        cities.forEach((t -> printKeyValue.accept(t, t.length())));

    }

The function above print the name of the cities and their length.

You can also write methods that has a BiConsumer as a paramenter.

Consider you are building a system that log users’ login activities with the following data model:

 record UserLoginReport(String name, int count, LocalDateTime lastLoggedIn);

You can create BiConsumer to log the activities as below:

    private static void reportLoginCount(UserLoginReport user, BiConsumer<String, Integer> loginCountConsumer) {
       loginCountConsumer.accept(user.name(), user.count()); 
    }
    private static void reportLoginTime(UserLoginReport user, BiConsumer<String, LocalDateTime> loginTimeConsumer) {
        loginTimeConsumer.accept(user.name(), user.lastLoggedIn());
    }

Now you can either create the consumers and pass into the methods or you can use lambda expressions for brevity (and coolness 😎)

    public static void main(String[] args) {
        //create 3 records
        var loginReport = List.of(
                new UserLoginReport("Alice", 10, LocalDateTime.now().minusDays(1)),
                new UserLoginReport("Bob", 20, LocalDateTime.now().minusHours(2)),
                new UserLoginReport("Charlie", 30, LocalDateTime.now()));
        
        //report login count
        loginReport.forEach(user -> reportLoginCount(user, (name, count) -> System.out.println(name + " logged in " + count + " times")));
        
        //report login time
        loginReport.forEach(user -> reportLoginTime(user, (name, time) -> System.out.println(name + " logged in at " + time)));
    }

The result would be like this:

Using BiConsumer for logging

Conclusion

In this post, I’ve shown you how to use BiConsumer in Java.

Leave a Comment