[Java] Stream (filter, map, forEach, reduce)

Overview

I was told "Write in stream!" And I didn't understand the merits, so I will summarize it.

What I found

--stream Very convenient. --The nesting of for and if statements is reduced, making it easier to see. --You don't have to instantiate the list. --Since you don't have to write .add, you can reduce the amount of code.

filter: Filtering conditions

List<String> tanakaList = 
    list.stream
        .filter(item -> item.getName.equals("Tanaka"))
        .collect(Collectors.toList());

--Decompose "list" with stream. --Get elements one by one from "list" and put them in "item". --Use filter to narrow down the objects with the name" Tanaka ". --Collect the disassembled streams and convert them to a list with collect. --Set to the return value "tanakaList".

--There are few nests. --You don't have to write the list instantiation yourself. --You don't have to write a setter.

(Since I took the number of lines with list.add (), I'm really glad that it disappeared ...)

--You can't branch like if-else. If you want to do it, you need to prepare two streams and write them as separate processes.

--If you use stream when sorting with sql and getting data, you have to write the sorting process again on the stream side, so I thought it should not be used in the process that cares about the sort order.

map: Value conversion

List<String> nameList = list.stream
                            .map(item -> item.getName)
                            .collect(Collectors.toList());

--Decompose "list" with stream. --Get elements one by one from "list" and put them in "item". --Get the name from "item" using the method with map and process the value of" item ". --Collect the disassembled streams and convert them to a list with collect. --Set to the return value "nameList".

--There are few nests. --You don't have to write the list instantiation yourself. --You don't have to write a setter. ――Since you can use the method, it was good that you could see what was in the item at a glance.

forEach: Loop processing

    list.stream
        .filter(item -> !item.getName.equals("Tanaka"))
        .forEach({
            item -> throw new Exception(
                "don't tanaka exception."
            )
        });

--Decompose "list" with stream. --Get elements one by one from "list" and put them in "item". --Refine the objects whose names are "not Tanaka" with filter. --Turn a loop with forEach, and if there is an object other than Tanaka, throw an Exception" It's not Tanaka ".

--There are few nests. --for (String tanaka: list) You don't even have to write it. ――It is easy to see what to do in which case.

reduce: element aggregation

    int total = list.stream()
                    .reduce((base, value) -> {
                        return base + value;
                    });

List contents

List<int> list = Lists.newArrayList();

        list.add(1);
        list.add(2);
        list.add(3);

--Decompose "list" with stream. --Get elements one by one from "list" in "base" and put "first element". --Get elements one by one from "list" in "value" and put "next element". --When reduce is executed for the first time, it is executed with base = 1 and value = 2. --The second time is executed with base = 2 and value = 3. --Return the sum of all and set it as the return value.

What I didn't understand

1: Why can I use a method like "item.getName"? -> There is a model class "Student" whose name is obtained from SQL. If list is defined by "List list", Since the list is decomposed by Stream and put in item, You can see that the item type is "Student". So you can use the methods that exist in the Student class! !! Since the getName method returns a String, there is no problem with the return value.

Student class

@Data
@Builder
class Student {
    private String name;
}

Stream.java

  List<Student> list = Lists.newArrayList();

  List<String> tanakaList = list.stream
                                .map(item -> item.getName.equals())
                                .collect(Collectors.toList())

Summary

I wasn't used to lambda, and stream was in a bad state, but when I tried using it, the amount of code was overwhelmingly reduced, so it was good. The biggest merit is that the depth of nesting has been eliminated at once. Once I knew it was so convenient, I thought I wouldn't use it as if I was obsessed with it in the future. So I thought I would be scared if there were any disadvantages I didn't know yet. (But I think I'll use it for a while, thank you for telling me ...)

Recommended Posts

[Java] Stream (filter, map, forEach, reduce)
[Java] Stream API / map
JAVA (Map)
Java8 list conversion with Stream map
[Java] Servlet filter
[JAVA] Stream type
Try Java 8 Stream
Java Stream API
[Java] forEach method
[Java] Map comparison
Studying Java 8 (Stream)
Java Stream termination
[Java] Stream processing
Java 9 Optional :: stream
[Java] Filter stack traces
[Java] Stream Collectors notes
[Java] Create a filter
Reasons to avoid for and map, filter, reduce, etc.
[Java] Stream API-Stream generation
Stream API map method
Enum reverse map Java
Java8 Stream API practice
Java8 Stream reduction operation
Java bidirectional map library
Java8 Stream Rough Summary
[Java] How to use Map
[Java11] Stream Summary -Advantages of Stream-
Java Stream API cheat sheet
Java Stream API in 5 minutes
Java8 stream, lambda expression summary
Use swift Filter and Map
How to use Java Map
[Java] Stream API --Stream termination processing
[Java] Stream API --Stream intermediate processing
Java Stream cannot be reused.
[Java] Introduction to Stream API
Use Redis Stream in Java
[Java11] Stream Usage Summary -Basics-
Java application for beginners: stream
[Java] Stream API intermediate operation