从for循环到Java 8 Stream示例

时间:2016-09-16 22:01:11

标签: java for-loop java-8 java-stream

我想要一个Java 8 Streams的简单示例来理解它。我有这个代码,返回一个免费的出租车。我想用使用Java 8流的等效代码替换这个for循环:

private List<Taxi> taxis = new ArrayList<Taxi>();

Taxi scheduleTaxi(){
    for (Taxi taxi : taxis) {
        if (taxi.isFree()) {
            return taxi;
        }
    }
    return null;
}

我遍历taxis列表,并评估taxi是否尊重条件。如果条件适用,我将停止循环并返回taxi

有什么建议吗?

3 个答案:

答案 0 :(得分:9)

使用最新的IntelliJ IDEA 2016.3 EAP(社区版或终极版),您可以自动转换它。只需将光标放在for循环上:

Idea

按Alt-Enter并选择&#34;替换为findFirst()&#34;:

Idea

瞧,已经完成了!

Idea

免责声明:我是IntelliJ IDEA开发人员。

答案 1 :(得分:7)

您正在寻找的是:

return taxis.stream()
            .filter(Taxi::isFree)
            .findFirst()
            .orElse(null);

以下是表达式步骤的列表及其返回类型和指向javadoc的链接

表达步骤 | 输入 | <强>替代
taxis | List<Taxi>
stream() | Stream<Taxi> | parallelStream()
filter(Taxi::isFree) | Stream<Taxi>
findFirst() | Optional<Taxi> | findAny()
orElse(null) | Taxi | none,见下文

filter(Taxi::isFree)来电正在使用method reference 它也可以使用lambda expression

编写
filter(t -> t.isFree())

或使用 lambda表达式块

filter(t -> {
    return t.isFree();
})

该参数还可以指定一种类型,更明确:

filter((Taxi t) -> { return t.isFree(); })

使它看起来更像anonymous class,相当于:

filter(new Predicate<Taxi>() {
    @Override
    public boolean test(Taxi t) {
        return t.isFree();
    }
})

作为@ 4castle mentioned in a comment,根据您的scheduleTaxi()方法的需要,您可能希望更改返回类型并跳过最后一步,以使调用者明白它可能不会能找到一辆出租车。

Optional<Taxi> scheduleTaxi() {
    return taxis.stream().filter(Taxi::isFree).findFirst();
}

答案 2 :(得分:0)

评论有点已经说过了,但我会更多地解释

private List<Taxi> taxis = new ArrayList<Taxi>();
Optional<Taxi> optTaxi = taxis.stream().filter(taxi -> taxi.isFree()).findFirst() //or findAny()

以下是逻辑上发生的事情:从列表中获取流后,使用filter基本上需要条件,检查列表中的哪些项目符合它们,并返回仅包含这些项目的流。然后findFirst/Any抓取第一个/任何项目并将其作为Optional返回。如果过滤没有“幸存”,则Optional将包含null

请记住,代码执行的顺序与我描述的不同,因为流的工作方式不同。如果你做filter(...).filter(...).filter(...),它就不会一遍又一遍地迭代。

返回您的代码:您可以返回Optional<Taxi>本身或将其解压缩并返回Taxi对象,该对象可以是null,具体取决于您的需要。