如何使用foreach循环遍历java 8流

Vad*_*zim 22 java foreach for-loop java-8 java-stream

假设我们尝试向java 8流应用一个可能抛出已检查异常的lambda:

Stream<String> stream = Stream.of("1", "2", "3");
Writer writer = new FileWriter("example.txt");

stream.forEach(s -> writer.append(s)); // Unhandled exception: java.io.IOException
Run Code Online (Sandbox Code Playgroud)

这不会编译.

一种解决方法是嵌套已检查的异常,RuntimeException但它使以后的异常处理变得复杂,而且它只是丑陋:

stream.forEach(s -> {
    try {
        writer.append(s);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
});
Run Code Online (Sandbox Code Playgroud)

另一种解决方法可能是转换有限的功能forEach,以普通的旧的foreach 循环是比较友好的检查的异常.

但天真的方法失败了:

for (String s : stream) { // for-each not applicable to expression type 'java.util.stream.Stream<java.lang.String>'
    writer.append(s);
}

for (String s : stream.iterator()) { // foreach not applicable to type 'java.util.Iterator<java.lang.String>'
    writer.append(s);
}
Run Code Online (Sandbox Code Playgroud)

更新

回答这个问题的一个技巧已经公布在为什么Stream <T>没有实现Iterable <T>?作为副答案,并没有真正回答这个问题本身.我认为这不足以将这个问题视为该问题的重复,因为他们会提出不同的问题.

Vad*_*zim 29

根据定义, foreach循环需要传入Iterable.

它可以通过匿名类来实现:

    for (String s : new Iterable<String>() {
        @Override
        public Iterator<String> iterator() {
            return stream.iterator();
        }
    }) {
        writer.append(s);
    }
Run Code Online (Sandbox Code Playgroud)

这可以通过lambda简化,因为它Iterable是一个功能接口:

    for (String s : (Iterable<String>) () -> stream.iterator()) {
        writer.append(s);
    }
Run Code Online (Sandbox Code Playgroud)

这可以转换为方法参考:

    for (String s : (Iterable<String>) stream::iterator) {
        writer.append(s);
    }
Run Code Online (Sandbox Code Playgroud)

使用中间变量或方法参数可以避免显式强制转换:

    Iterable<String> iterable = stream::iterator;
    for (String s : iterable) {
        writer.append(s);
    }
Run Code Online (Sandbox Code Playgroud)

在maven中心还有一个StreamEx库,它具有可迭代流和开箱即用的其他特权.


以下是一些最受欢迎的问题和方法,它们提供了lambda和流中已检查异常处理的变通方法:

抛出异常的Java 8 Lambda函数?

Java 8:Lambda-Streams,按方法过滤,具有异常

如何从Java 8流中抛出CHECKED异常?(不将其包装到未经检查的例外中)

Java 8:在lambda表达式中强制检查异常处理.为什么强制,不是可选的?

jOOλ未选中

科特林 ;)

  • [更普遍的黑客](http://stackoverflow.com/questions/31637892/throwing-exception-from-lambda/31638189#31638189)可用于任意高阶函数,而不仅仅是'forEach`. (3认同)

归档时间:

查看次数:

10386 次

最近记录:

8 年,2 月 前