是否不鼓励在 java 流中使用 if ?
Is it discouraged to use if in java streams?
考虑以下问题:我应该关掉房间里所有的灯。房间包含在一套房间里。是否不鼓励使用 forEach 和 if? (我读了我所有的讲义,他们都没有提到 .forEach(p -> {if... construct.. 但是我发现它是最简单的。如果不鼓励,我该如何解决问题?为什么不鼓励?
public void turnOffLampsInRooms(Set<Room> rooms) {
lamps.stream()
.forEach(p -> {if (p.getRoom() != null && rooms.contains(p.getRoom())) {
p.turnOff();
}
});
}
不使用 if
,而是使用以下条件进行过滤:
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom()))
.forEach(SmartLamp::turnOff);
注意方法参考 SmartLamp::turnOff
的使用,它通常优于等效的 lambda p -> p.turnOff()
.
事实是,您使用优化良好的 Stream API,条件稍慢 if
。它的语法是正确的,它可以正常工作,但它看起来不太好,而且对于大量数据来说速度较慢。
首先,您应该将 if
语句移动到 .filter
流调用:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null && rooms.contains(p.getRoom()))
.forEach(p -> p.turnOff()); // conditions checked already
}
接下来,.filter
可以拆分成单独的:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom())) // the same meaning
.forEach(p -> p.turnOff());
}
最后更改对方法引用的调用:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom()))
.forEach(SmartLamp::turnOff); // method reference
}
主要优点是流优化,但也更容易逐步阅读流的作用。
考虑以下问题:我应该关掉房间里所有的灯。房间包含在一套房间里。是否不鼓励使用 forEach 和 if? (我读了我所有的讲义,他们都没有提到 .forEach(p -> {if... construct.. 但是我发现它是最简单的。如果不鼓励,我该如何解决问题?为什么不鼓励?
public void turnOffLampsInRooms(Set<Room> rooms) {
lamps.stream()
.forEach(p -> {if (p.getRoom() != null && rooms.contains(p.getRoom())) {
p.turnOff();
}
});
}
不使用 if
,而是使用以下条件进行过滤:
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom()))
.forEach(SmartLamp::turnOff);
注意方法参考 SmartLamp::turnOff
的使用,它通常优于等效的 lambda p -> p.turnOff()
.
事实是,您使用优化良好的 Stream API,条件稍慢 if
。它的语法是正确的,它可以正常工作,但它看起来不太好,而且对于大量数据来说速度较慢。
首先,您应该将 if
语句移动到 .filter
流调用:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null && rooms.contains(p.getRoom()))
.forEach(p -> p.turnOff()); // conditions checked already
}
接下来,.filter
可以拆分成单独的:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom())) // the same meaning
.forEach(p -> p.turnOff());
}
最后更改对方法引用的调用:
public void turnOffLampsInRooms(Set<Room> rooms) {
Set<SmartLamp> set = new HashSet<>(lamps);
set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom()))
.forEach(SmartLamp::turnOff); // method reference
}
主要优点是流优化,但也更容易逐步阅读流的作用。