假设我们尝试将可能引发检查异常的lambda应用于Java 8流:
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
这不会编译。
一种解决方法是将检查后的异常嵌套在其中,RuntimeException
但是这会使以后的异常处理变得复杂,而且很丑陋:
stream.forEach(s -> {
try {
writer.append(s);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
另一种解决方法可能是转换限制功能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);
}
更新资料
为何在Stream <T>不实现Iterable <T>的地方贴了一个回答该问题的技巧。作为副答案本身并不能真正回答该问题。我认为这不足以使这个问题与该问题重复,因为他们问的是不同的事情。
根据定义, foreach循环需要传入一个Iterable。
可以使用匿名类实现:
for (String s : new Iterable<String>() {
@Override
public Iterator<String> iterator() {
return stream.iterator();
}
}) {
writer.append(s);
}
使用lambda可以简化此过程,因为它Iterable
是一个功能接口:
for (String s : (Iterable<String>) () -> stream.iterator()) {
writer.append(s);
}
可以将其转换为方法参考:
for (String s : (Iterable<String>) stream::iterator) {
writer.append(s);
}
使用中间变量或方法参数可以避免显式强制转换:
Iterable<String> iterable = stream::iterator;
for (String s : iterable) {
writer.append(s);
}
Maven Central中还有StreamEx库,它具有开箱即用的可迭代流和其他特权。
以下是一些最流行的问题和方法,它们提供了有关lambda和流中检查异常处理的解决方法:
Java 8:Lambda-Streams,按方法进行异常过滤
如何从Java 8流中引发CHECKED异常?(不将其包装为未经检查的异常)
Java 8:lambda表达式中的强制检查异常处理。为什么是强制性的而不是可选性的?
科特林 ;)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句