Java Lambda表示式forEach無法跳出迴圈的解決思路

Soochow發表於2019-08-05

Java Lambda表示式forEach無法跳出迴圈的解決思路

如果你使用過forEach方法來遍歷集合,你會發現在lambda表示式中的return並不會終止迴圈,這是由於lambda的底層實現導致的,看下面的例子:

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    list.forEach(s -> {
        System.out.println("s = " + s);
        if (s.equals("b")) {
            return;
        }
    });
}
//返回結果:
//s = a
//s = b
//s = c

可以看到在forEach方法中即是採用了return,迴圈卻仍在繼續,那有什麼辦法能跳出迴圈呢?

可以通過拋異常的方法:

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    try {
        list.forEach(s -> {
            System.out.println("s = " + s);
            if (s.equals("b")) {
                throw new RuntimeException();
            }
        });
    }catch (Exception e){}
}
//返回結果:
//s = a
//s = b

但仔細想想,這樣也太挫了,其實可以換一種思路,跳出的前提肯定是滿足了某一條件的,所以可以使用anyMatch()方法:

anyMatch()裡接收一個返回值為boolean型別的表示式,只要返回true就會終止迴圈,這樣可以將業務邏輯寫在返回判斷結果前。

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    list.stream().anyMatch(s -> {
        System.out.println("do something");
        System.out.println("s=" + s);
        return s.equals("b");
    });
}
// do something
// s=a
// do something
// s=b

同理,採用類似的思路可以使用filter()方法,思路是一樣的,其中findAny表示只要找到滿足的條件時停止。

public static void main(String[] args) {
    List<String> list = Lists.newArrayList();
    list.add("a");
    list.add("b");
    list.add("c");

    list.stream().filter(s -> {
        System.out.println("s=" + s);
        return s.equals("b");
    }).findAny();
}
//返回結果:
//s = a
//s = b

相關文章