问题描述
我认为流API在这里使代码更容易阅读。我发现一些相当烦人的东西。
Stream
interface( java.util.stream.Stream
)扩展了 AutoClosable
interface( java.lang.AutoCloseable
) 所以如果你想正确关闭你的流必须使用资源试用。
清单1 。不太好,流未关闭。
public void noTryWithResource(){
Set< Integer> photos = new HashSet< Integer>(Arrays.asList(1,2,3));
@SuppressWarnings(资源)列表< ImageView> collect = photos.stream()
.map(photo - > new ImageView(new Image(String.valueOf(photo))))。collect(Collectors。< ImageView> toList());
}
清单2 。有两个尝试:(
public void tryWithResource(){
Set< Integer> photos = new HashSet< Integer& ;(Arrays.asList(1,2,3));
try(Stream< Integer> stream = photos.stream()){
try(Stream< ImageView> map = stream
.map(photo - > new ImageView(new Image(String.valueOf(photo))))){
列表< ImageView> collect = map.collect(Collectors。< ImageView> toList ));
}
}
}
清单3 。由于 map
返回一个流,所以 stream()
和 map()
函数必须关闭。
public void tryWithResource2(){
Set< Integer> photos = new HashSet< Integer>(Arrays.asList(1,2,3));
try(Stream< Integer> stream = photos.stream();
流< ImageView> map = stream
.ma p(照片 - > new ImageView(new Image(String.valueOf(photo))))){
列表< ImageView> collect = map.collect(Collectors。< ImageView> toList());
}
}
我给的例子没有任何意义。为了示例,我将 Path
替换为具有 Integer
的jpg图像。但是不要让你分心这些细节。
这些可自动关闭的流是最好的方式。
我不得不说我不满意我显示的3个选项中的任何一个。
你觉得怎么样?还有其他更优雅的解决方案?
您正在使用 @SuppressWarnings(resource)
可能会禁止对未关闭资源的警告。这不是 javac
发出的警告之一。网页搜索似乎表明,如果 AutoCloseable
未关闭,Eclipse会发出警告。
这是一个合理的警告,到,介绍了 AutoCloseable
:
但是, for AutoCloseable
被放宽以删除必须关闭子句。现在,它部分地表示,
Lambda专家组中广泛讨论了此问题; 总结了决定。除此之外,它还提到了 AutoCloseable
规范(如上所述)和 BaseStream
规范(由其他答案引用) 。它还提到可能需要调整Eclipse代码检查器的变更语义,大概不会无条件地为 AutoCloseable
对象发出警告。显然这个消息没有得到Eclipse的人,或者他们还没有改变。
总之,如果Eclipse的警告引导你认为你需要关闭所有 AutoCloseable
对象,这是不正确的。只有某些具体的 AutoCloseable
对象需要关闭。 Eclipse需要修复(如果还没有)不为所有 AutoCloseable
对象发出警告。
I thought that the stream API was here to make the code easier to read.I found something quite annoying. The Stream
interface (java.util.stream.Stream
) extends the AutoClosable
interface (java.lang.AutoCloseable
)
So if you want to correctly close your streams you have to use try with resources.
Listing 1. Not very nice, streams are not closed.
public void noTryWithResource() {
Set<Integer> photos = new HashSet<Integer>(Arrays.asList(1, 2, 3));
@SuppressWarnings("resource") List<ImageView> collect = photos.stream()
.map(photo -> new ImageView(new Image(String.valueOf(photo)))).collect(Collectors.<ImageView>toList());
}
Listing 2. With 2 imbricated try :(
public void tryWithResource() {
Set<Integer> photos = new HashSet<Integer>(Arrays.asList(1, 2, 3));
try (Stream<Integer> stream = photos.stream()) {
try (Stream<ImageView> map = stream
.map(photo -> new ImageView(new Image(String.valueOf(photo))))) {
List<ImageView> collect = map.collect(Collectors.<ImageView>toList());
}
}
}
Listing 3. As map
returns a stream, both the stream()
and the map()
functions have to be closed.
public void tryWithResource2() {
Set<Integer> photos = new HashSet<Integer>(Arrays.asList(1, 2, 3));
try (Stream<Integer> stream = photos.stream();
Stream<ImageView> map = stream
.map(photo -> new ImageView(new Image(String.valueOf(photo))))) {
List<ImageView> collect = map.collect(Collectors.<ImageView>toList());
}
}
The example I give does not make any sense. I replaced Path
to jpg images with Integer
, for the sake of the example. But don't let you distract by these details.
What is the best way to go around with those auto closable streams.I have to say I'm not satisfied with any of the 3 options I showed.What do you think? Are there yet other more elegant solutions?
You're using @SuppressWarnings("resource")
which presumably suppresses a warning about an unclosed resource. This isn't one of the warnings emitted by javac
. Web searches seem to indicate that Eclipse issues warnings if an AutoCloseable
is left unclosed.
This is a reasonable warning according to the Java 7 specification that introduced AutoCloseable
:
However, the Java 8 specification for AutoCloseable
was relaxed to remove the "must be closed" clause. It now says, in part,
This issue was discussed extensively within the Lambda expert group; this message summarizes the decision. Among other things it mentions changes to the AutoCloseable
specification (cited above) and the BaseStream
specification (cited by other answers). It also mentions the possible need to adjust the Eclipse code inspector for the changed semantics, presumably not to emit warnings unconditionally for AutoCloseable
objects. Apparently this message didn't get to the Eclipse folks or they haven't changed it yet.
In summary, if Eclipse warnings are leading you into thinking that you need to close all AutoCloseable
objects, that's incorrect. Only certain specific AutoCloseable
objects need to be closed. Eclipse needs to be fixed (if it hasn't already) not to emit warnings for all AutoCloseable
objects.
这篇关于Java 8 Streams并尝试使用资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!