假设我有3个要关闭的Scanner实例。
我可以做
sc.close()
对于每个扫描仪。
或者我可以做类似的事情
for (Scanner sc: new Scanner[]{sc1,sc2,sc3}) {
sc.close();
}
使用Java8有没有更简单的方法?
类似的东西?
{sc1,sc2,sc3}.forEach((sc) -> sc.close());
虽然有时代码的长度与其质量之间存在相关性,但这并不是选择代码的好标准。
我可能会使用varargs并执行以下操作:
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);
如果实例化与处置分离,则使用Guava的com.google.常见的木卫一。更接近。
由于Java7,您应该使用try与资源
try(Scanner sc1 = new Scanner("");
Scanner sc2 = new Scanner("");
Scanner sc3 = new Scanner("")){
}
//all scanners get closed implicitly
所以你根本不需要任何代码。
all for each或stream构造的问题是,从理论上讲,如果第一个close()
在调用底层源代码的close()
方法时出现异常而失败,那么以下扫描程序将无法关闭。扫描仪。close()
实现捕获任何IOException,但不会捕获可能发生的其他异常。
try-with-resources构造处理这个问题,而循环不处理。
编辑:虽然您的问题针对的是更一般的方法,但上述解决方案是对您的特定问题的响应:处理自动关闭的
资源,在任何情况下都应与try-with-resources结构一起使用,完全不需要对封闭方法进行特殊处理(=特定问题的最短解决方案)。
关于处理任意项(没有资源)的更一般问题,Java至少有两个选项:
从数组/Varargs创建List并迭代它
for(YourItemType item : Arrays.asList(your,items,here)) {
//do something
}
从数组/Varargs创建流并将函数应用到它
Stream.of(your,items,here).forEach(item -> { doSomething});
当然,“doSomething”可以替换为方法参考
Stream.of(your,items,here).forEach(this::myMethod);
...
void myMethod(YourItemType item){
//doSomething
}
这种方法的问题是,必须在lambda表达式中显式处理选中的异常。让我们以上面的示例为例,让myMethod
抛出一个选中的异常
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
中,它获取类外创建的资源,所有这些资源都应该在调用Cloch()
时安全关闭
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
}
}
}
一旦您有了这样一个帮助类,您就可以通过使用资源尝试再次使用它。
try(CompositeAutoCloseable cac = new CompositeAutoCloseable(sc1,sc2,sc3)) {
//do something
}
我把它留给你来决定,如果这与初始解决方案相比是有意义的;)
问题内容: 有一个对象,是否有比列表理解更快,更好或更正确的方法来获取迭代器返回的对象的列表? 问题答案:
问题内容: 我有一个Python脚本,该脚本接受一个整数列表作为输入,我需要一次处理四个整数。不幸的是,我无法控制输入,或者将其作为四元素元组的列表传递。目前,我正在以这种方式对其进行迭代: 不过,这看起来很像“C-think”,这让我怀疑有一种更像蟒蛇的方式来处理这种情况。列表在迭代后被丢弃,因此不需要保留它。也许这样更好? 不过,仍然感觉不太正确。 问题答案: 从Python的itertool
问题内容: 对于Java语言有些陌生,我试图使自己熟悉所有可能遍历列表(或其他集合)的方式(或至少是非病理性方式)以及每种方式的优缺点。 给定一个对象,我知道以下遍历所有元素的方式: 基本的for 循环(当然,也有等效的while/ do while循环) 注意:正如@amarseillan指出的那样,这种形式对于在s上进行迭代是一个糟糕的选择,因为该方法的实际实现可能不如使用时有效。例如,实
由于对Java语言有些陌生,我正在尝试熟悉所有可以通过列表(或者其他集合)进行迭代的方法(或者至少是非病态的方法),以及每种方法的优缺点。 给定一个对象,我知道以下循环所有元素的方法: 注意:正如@Amarseillan所指出的,对于迭代s,此表单是一个糟糕的选择,因为方法的实际实现可能不如使用时那样高效。例如,实现必须遍历i之前的所有元素以获得第i个元素。 在上面的示例中,实现没有办法“保留它的
问题内容: 我有一个Python脚本,该脚本接受一个整数列表作为输入,我需要一次使用四个整数。不幸的是,我无法控制输入,或者将其作为四元素元组的列表传递。目前,我正在以这种方式对其进行迭代: 不过,它看起来很像“ C思维”,这使我怀疑还有一种处理这种情况的更Python的方法。列表在迭代后被丢弃,因此不需要保留。也许像这样会更好? 不过,还是不太“正确”。 问题答案: 从Python的iterto
主要内容:如何为每一行添加序号?本文章将介绍Thymeleaf标准表达式语法中的概念。我们将使用标记在模板中迭代产品列表。 编辑源代码以便将产品列表显示为表格行。已经将类的对象列表设置为具有变量名称的上下文模型(参考:中的实现)。 如果要上机实践,请参考:Thymeleaf+SpringMVC5示例项目。这里不再重复创建项目的过程,这里将只介绍如何使用标准表达式和标签。 这里创建一个Maven Web项目: thymeleaf-