Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why java8 streams consumer andThen method?

I am new to Java 8, just want to ask what is the difference in performance between the two code snippets below.

I know both work, but I am wondering why the Java team created Consumer::andThen method when I can use the normal approach.

List<String> list = Arrays.asList("aaa","cccc","bbbb");
List<String> list2 = new ArrayList<>();

//Approach 1

list.stream().forEach(x -> {
            list2.add(x);
            System.out.println(x);
        });

//Approach 2

Consumer<String> c1 = s -> list2.add(s);
Consumer<String> c2 = s -> System.out.println(s);

list.stream().forEach(c1.andThen(c2));

IMO, approach1 is better, why approach2 again? If both are same, then why andThen() method is created? I guess there must be reason they've created.

In other words, when exactly is the andThen() method really helpful?

like image 909
john Avatar asked Dec 06 '22 09:12

john


1 Answers

I agree that is makes less sense to create a separate Consumer<String> instance for each statement just for the sake of using andThen.

However, if you already have two Consumer<String> instances (c1 and c2), and you need to execute both, you could either write:

list.forEach(x -> {
        c1.accept(x);
        c2.accept(x);
    });

or

list.forEach(c1.andThen(c2));

In this case, the latter is clearly cleaner.

EDIT:

I'd like to expand on the case when you create your own Consumers (i.e. not re-using pre-existing ones). When you assign a lambda expression to a Consumer variable, you can use that Consumer instance in multiple places instead of duplicating the lambda expression. That is true for any functional interface.

Once you decide to use a Consumer variable, the decision of whether to have a single Consumer implementing complex logic or 2 simpler Consumers, each implementing part of the logic, depends on whether there is a need to be able to execute just part of the logic in some cases (or changing the order in which parts of the logic are executed).

Having c1 and c2 allows you either of the following options:

list.forEach(c1);
list.forEach(c2);
list.forEach(c1.andThen(c2));
list.forEach(c2.andThen(c1));

If you had a single consumer that does the logic of both c1 and c2, you have less flexibility.

like image 102
Eran Avatar answered Jan 03 '23 22:01

Eran