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;
}
}
The theme Stream and the for statement for comparison are prepared below.
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.
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
It becomes.
Both execution results
Sato Suzuki
It becomes.
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.
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.
Introduction to Java Stream API How to remove duplicate elements from two arrays in Java Stream and make various original classes
Recommended Posts