当前位置: 首页 > 知识库问答 >
问题:

迭代非列表的最短方法?

丰辰沛
2023-03-14

假设我有3个要关闭的Scanner实例。

我可以做

sc.close()

对于每个扫描仪。

或者我可以做类似的事情

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

使用Java8有没有更简单的方法?

类似的东西?

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

共有3个答案

连昊天
2023-03-14

虽然有时代码的长度与其质量之间存在相关性,但这并不是选择代码的好标准。

我可能会使用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);
戎志勇
2023-03-14

如果实例化与处置分离,则使用Guava的com.google.常见的木卫一。更接近。

蓝星辰
2023-03-14

由于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循环) 注意:正如@a​​marseillan指出的那样,这种形式对于在s上进行迭代是一个糟糕的选择,因为该方法的实际实现可能不如使用时有效。例如,实

  • 由于对Java语言有些陌生,我正在尝试熟悉所有可以通过列表(或者其他集合)进行迭代的方法(或者至少是非病态的方法),以及每种方法的优缺点。 给定一个对象,我知道以下循环所有元素的方法: 注意:正如@Amarseillan所指出的,对于迭代s,此表单是一个糟糕的选择,因为方法的实际实现可能不如使用时那样高效。例如,实现必须遍历i之前的所有元素以获得第i个元素。 在上面的示例中,实现没有办法“保留它的

  • 问题内容: 我有一个Python脚本,该脚本接受一个整数列表作为输入,我需要一次使用四个整数。不幸的是,我无法控制输入,或者将其作为四元素元组的列表传递。目前,我正在以这种方式对其进行迭代: 不过,它看起来很像“ C思维”,这使我怀疑还有一种处理这种情况的更Python的方法。列表在迭代后被丢弃,因此不需要保留。也许像这样会更好? 不过,还是不太“正确”。 问题答案: 从Python的iterto

  • 主要内容:如何为每一行添加序号?本文章将介绍Thymeleaf标准表达式语法中的概念。我们将使用标记在模板中迭代产品列表。 编辑源代码以便将产品列表显示为表格行。已经将类的对象列表设置为具有变量名称的上下文模型(参考:中的实现)。 如果要上机实践,请参考:Thymeleaf+SpringMVC5示例项目。这里不再重复创建项目的过程,这里将只介绍如何使用标准表达式和标签。 这里创建一个Maven Web项目: thymeleaf-