迭代非列表最短的方法?

假设我有3个扫描器实例,我想closures。

我可以

sc.close() 

为每个扫描仪。

或者我可以做类似的事情

 for (Scanner sc: new Scanner[]{sc1,sc2,sc3}) { sc.close(); } 

用Java 8做这个有什么简单的方法吗?

类似的东西?

 {sc1,sc2,sc3}.forEach((sc) -> sc.close()); 

从Java 7开始,您应该使用try-with-resources

 try(Scanner sc1 = new Scanner(""); Scanner sc2 = new Scanner(""); Scanner sc3 = new Scanner("")){ } //all scanners get closed implicitly 

所以你根本不需要任何代码。

所有for-each或stream结构的问题是,理论上 – 如果第一个close()在调用底层源代码的close()方法时失败,则下面的扫描程序不会closures。 Scanner.close()实现捕获任何IOException,但不会发生其他exception。

try-with-resources结构处理的是,循环没有。


编辑 :虽然你的问题针对一个更一般的方法,上面的解决scheme是对你的特定问题的回应:处理AutoCloseable资源,这应该在任何情况下与try-with-resources结构一起使用,不需要特殊处理closures的方法在所有(=最短的解决scheme,您的特定问题)。

关于处理任意项目(没有资源)的更一般的问题,Java至less有两个选项:

从一个数组/可变参数创build一个列表并迭代它

 for(YourItemType item : Arrays.asList(your,items,here)) { //do something } 

从数组/可变参数创build一个stream,并将函数应用于它

 Stream.of(your,items,here).forEach(item -> { doSomething}); 

当然,“doSomething”可以用方法引用来replace

 Stream.of(your,items,here).forEach(this::myMethod); ... void myMethod(YourItemType item){ //doSomething } 

这种方法的问题是,检查exception必须在lambdaexpression式中明确处理。 让我们拿上面的例子,让myMethod抛出一个检查的exception

 void myMethod(YourItemType item) throws Exception 

在这种情况下,你的stream声明将不得不看起来像

 Stream.of(your,items,here).forEach(item -> { try { myMethod(item); } catch (Exception e){ //omit or throw new RuntimeException(e); }; 

这看起来不错。 但是我们可以把lambda体放在一个单独的方法中

 void myMethodQuietly(YourItemType item) { try { myMethod(item); }catch(Exception e){ //omit or throw new RuntimeException(e); } } Stream.of(your,items,here).forEach(this::myMethodQuietly); 

这种方法可能会对您的特定资源问题感兴趣。 我们可以把所有这一切都放到一个CompositeAutoCloseable ,这个接口可以调用close()

 public class CompositeAutoCloseable implements AutoCloseable { private List<Closeable> resources; public CompositeAutoCloseable(Closeable... resources) { this.resources = Arrays.asList(resources); //you could use a stream here too } @Override public void close() { this.resources.stream().forEach(this::closeQuietly); } void closeQuietly(Closeable res) { if(res == null) { return; } try { res.close(); }catch(Exception e){ //omit } } } 

一旦你有这样一个辅助class,你可以再次尝试与资源使用它。

 try(CompositeAutoCloseable cac = new CompositeAutoCloseable(sc1,sc2,sc3)) { //do something } 

我把它留给你决定,与初始解决scheme相比这是否合理;)

如果实例化与处置分离,请使用Guava的com.google.common.io.Closer 。

虽然代码的长度与其质量之间有时是相关的,但这不是用来select代码的好的标准。

我可能会使用可变参数,并做这样的事情:

 private void closeScanner(Scanner... scanners) { // Faff around with Java 8 in here if you like. for (Scanner s : scanners) { s.close(); } } // Some code. closeScanner(s, t, u);