[Java] Generate a narrowed list from multiple lists using the Stream API

Data example

Prepare the following data.

** Staff list **

name rollType
Sato 1
Suzuki 2
Takahashi 3
Tanaka 4
Ito 5

** Roll list **

rollType owner
1 true
2 true
3 false
4 false
5 false

Isn't it a structure that you often see in DB? What if you want a list of Staff with a rollType whose owner is true? I think "bring it from DB with INNER JOIN", but this time I will assume that the list exists independently.

The list actually prepared is as follows.

list.java


List<Staff> staffList = Arrays.asList(
        new Staff("Sato", 1), 
        new Staff("Suzuki", 2), 
        new Staff("Takahashi", 3), 
        new Staff("Tanaka", 4), 
        new Staff("Ito", 5)
);

List<Roll> rollList = Arrays.asList(
        new Roll(1, true), 
        new Roll(2, true), 
        new Roll(3, false), 
        new Roll(4, false), 
        new Roll(5, false)
);

Staff and Roll are the following classes.

SampleClass.java


private class Staff {
    private final String name;
    private final Integer rollType;

    public Staff(String name, Integer rollType) {
        this.name = name;
        this.rollType = rollType;
    }

    public String getName() {
        return this.name;
    }

    public Integer getRollType() {
        return this.rollType;
    }
}

private class Roll {
    private final Integer rollType;
    private final boolean owner;

    public Roll(Integer rollType, boolean owner) {
        this.rollType = rollType;
        this.owner = owner;
    }

    public Integer getRollType() {
        return this.rollType;
    }

    public boolean isOwner() {
        return this.owner;
    }
}

Actually fetch

The theme Stream and the for statement for comparison are prepared below.

Notation in for statement

Main.java


for (Staff staff : StaffList) {
    for (Roll roll : RollList) {
        if (roll.isOwner()) {
            if (staff.getRollType() == roll.getRollType()) {
                System.out.println(staff.getName());
            }
        }
    }
}

It's easy to understand.

Notation in Stream

Main.java


staffList.stream()
        .filter( // 1.
                staff ->
                        rollList.stream()
                                .filter(roll -> roll.isOwner()) //2.
                                .anyMatch(roll -> // 3.
                                        staff.getRollType() == roll.getRollType()
                                )
        )
        .forEach(staff -> System.out.println(staff.getName()));

To briefly explain

  1. Filter Staff whose internal condition is true
  2. Generate a Roll list for which owner is true
  3. Returns true if Staff's rollType is in the Roll list

It becomes.

Both execution results

Sato Suzuki

It becomes.

Comparison of execution time

Generate a new list that meets the conditions using each notation (for uses add for an empty list, Stream uses Collector), The execution time when this is repeated 1000000 times is as follows.

notation Execution time(ms)
For 135
Stream 889

There is a 6-fold difference. I tried it several times, but this difference did not shrink significantly (obviously).

In addition to the fact that Stream is not originally fast, it seems that the fact that Stream is generated one by one in the filter has a big impact.

If it's a simple loop, it's more stream-like than the for statement, but it's an idea that there is a difference in performance so far.

Summary

Achieve a pseudo INNER JOIN using Stream By nesting filters, it is possible to handle lists such as lists ... Use the For statement quietly from a performance standpoint

If there is a method that can make the same operation faster, please comment.

References

Introduction to Java Stream API How to remove duplicate elements from two arrays in Java Stream and make various original classes

Recommended Posts

[Java] Generate a narrowed list from multiple lists using the Stream API
Data processing using stream API from Java 8
Try using the Stream API in Java
[Java] How to operate List using Stream API
Using the database (SQL Server 2014) from a Java program 2018/01/04
[java8] To understand the Stream API
I tried using Java8 Stream API
Sort by multiple conditions using Java Stream
Hit the Salesforce REST API from Java
Try using the Emotion API from Android
Find the difference from a multiple of 10
[Java] From two Lists to one array list
ChatWork4j for using the ChatWork API in Java
[Java] Get and display the date 10 days later using the Time API added from Java 8.
Java Stream API
Create Scala Seq from Java, make Scala Seq a Java List
Try accessing the dataset from Java using JZOS
Try using the COTOHA API parsing in Java
Ssh connect using SSHJ from a Java 6 app
Output the maximum value from the array using Java standard output
Studying java8 (such as reading a file using Stream)
[Java] Sort the list using streams and lambda expressions
Use Java lambda expressions outside of the Stream API
Extract a specific element from the list of objects
[Java] Stream API / map
Get to the abbreviations from 5 examples of iterating Java lists
Create a MOB using the Minecraft Java Mythicmobs plugin | Preparation 1
How to play MIDI files using the Java Sound API
Generate Stream from an array of primitive types in Java
Get a non-empty collection from an Optional stream in java
How to get the latest live stream ID for a channel without using the YouTube Data API
AWS Elastic Beanstalk # 1 with Java starting from scratch-Building a Java web application environment using the EB CLI-
Java Stream API cheat sheet
[Java] Introduction to Stream API
Using Docker from Java Gradle
Make a rhombus using Java
[Java] Combine multiple Lists (Collections)
[Java] Stream API intermediate operation
Sort List in descending order in Java and generate a new List non-destructively
Sample of using Salesforce's Bulk API from Java client with PK-chunking
Efficiently extract multiple elements from the list randomly and without duplication
Access the in-memory data grid Apache Ignite from a Java client
Easy way to create a mapping class when using the API
Effective Java Item 25 Select a list from an array First half
Leverage Either for individual exception handling in the Java Stream API
[Gradle] Build a Java project with a configuration different from the convention
A story that I wanted to write a process equivalent to a while statement with the Stream API of Java8