简体   繁体   English

不鼓励在 java 流中使用 if 吗?

[英]Is it discouraged to use if in java streams?

Consider the following problem: I should turn-off all the lamps in a room.考虑以下问题:我应该关掉房间里的所有灯。 The room is contained in a Set rooms.该房间包含在 Set 房间中。 Is it discouraged to use forEach and if?不鼓励使用 forEach 和 if 吗? (I read all my lecture notes nowhere did they mention the .forEach(p -> {if... construct.. However I found it the simplest. If it is discouraged how can I solve the problem otherwise? And why is it discouraged? (我读了我所有的讲义,他们没有提到 .forEach(p -> {if...construct.. 但是我发现它是最简单的。如果不鼓励我如何解决问题?为什么不鼓励它?

public void turnOffLampsInRooms(Set<Room> rooms) {
    Set<SmartLamp> set = new HashSet<>(lamps);
    set.stream()
    .forEach(p -> {if (p.getRoom() != null && rooms.contains(p.getRoom())) {
        p.turnOff();
    }   
    });
}

Rather than using if , filter using the conditions:而不是使用if ,使用条件过滤:

set.stream()
.filter(p -> p.getRoom() != null)
.filter(p -> rooms.contains(p.getRoom()))
.forEach(SmartLamp::turnOff);

Note the use of the method reference SmartLamp::turnOff , which is generally preferred to the equivalent lambda p -> p.turnOff() .请注意方法引用SmartLamp::turnOff ,它通常比等效的 lambda p -> p.turnOff()

The fact is, you use well optimized Stream API with a bit slower if conditions.事实是,您使用优化良好的 Stream API, if条件稍慢一些。 Its syntax is correct, it works as should, but it doesn't look nice and for huge amount of data is slower.它的语法是正确的,它可以正常工作,但它看起来不太好,而且对于大量数据来说速度较慢。

Firstly you should move the if statement to .filter stream call:首先,您应该将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
}

Next, the .filter can be split into separated ones:接下来, .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());
}

And finally change the call to method reference:最后更改对方法引用的调用:

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
}

The main advantage is stream optimization, but it also is far easier to read step-by-step what does the streaming do.主要优点是流优化,但也更容易一步步阅读流的作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM