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

Java流关闭方法模糊行为

况安然
2023-03-14

给定这个Java类:

class MyClass {
    private int value;

    public MyClass(int value) {
        this.value = value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }

    @Override
    public String toString() {
        return "Value: " + value;
    }
}

给出以下Java代码:

Consumer<MyClass> cons = mc -> mc.setValue(mc.getValue() * mc.getValue());

List<MyClass> list = new ArrayList<>();
list.add(new MyClass(1));
list.add(new MyClass(2));
list.add(new MyClass(3));

System.out.println(list);

我得到了这个输出:[值:1,值:2,值:3]

当我运行这段代码时:

list.stream().peek(cons).close();   //1
System.out.println(list);

我期望得到输出[Value:1,Value:4,Value:9],但我得到了[Value:1,Value:2,Value:3],所以列表中的元素没有被修改。

但是当我运行这个时:

list.stream().forEach(cons);        //2

这是:

list.stream().peek(cons).count();   //3

我两次都得到了我期望的输出([Value: 1, Value: 4, Value: 9])

为什么第//1行没有给我这个输出?我想这是因为close():这个方法是如何工作的?

谢谢你的支持。

共有2个答案

漆雕伟志
2023-03-14

peek是一种中间操作,不会触发流处理管道,除非其中有终端操作符。所以声明,

list.stream().peek(cons).close();

没有终端操作,并且根本不会触发流管道,因此不会执行使用者,从而导致您观察到的结果。该列表保持不变。然而,这不是由于流中的关闭方法造成的。

在其他两种情况下,

list.stream().forEach(cons);        
list.stream().peek(cons).count();  

您有每个和计数的终端操作,因此执行消费者导致修改原始列表。

周和安
2023-03-14

关闭,无论是否有终端操作都会被触发;如果它用于尝试使用资源关闭会在流本身上调用;但无论哪种方式,它都不是终端操作。所以它既不是中间一个,也不是终端一个——它有点特殊。

    Stream<Integer> s2 = Stream.of(1, 2, 3);
    s2.onClose(() -> System.out.println("Closing 2"));
    s2.close(); // will print Closing 2

但也看到了这一点:

    try (Stream<Integer> s = Stream.of(1, 2, 3)) {
        s.onClose(() -> System.out.println("Closing"));
        s.filter(x -> x > 1)
         .peek(x -> System.out.println("foud one"));
    }

运行此命令,您自己可以看到,在第二个示例中,没有触发peek,但关闭。

因此,为了回答您的问题,正确的措辞应该是:close不是终端操作,因此您的流管道不会执行

 类似资料:
  • 问题内容: 这是一个无法编译的代码示例: 有人可以告诉我这些方法模棱两可的原因吗?先感谢您。 问题答案: 考虑方法签名 和 在装箱和拆箱之前,通话不会是模棱两可的。为了确保与Java的早期版本兼容,该调用将保持明确。因此,重载解决方案的第一阶段不允许装箱,拆箱或可变Arity调用,这些操作都是在同一时间引入的。可变Arity调用是通过为最后一个参数(而不是数组)传递参数序列来调用varargs方法

  • 问题内容: 如果我们使用Java 8 Stream,例如何时关闭此流? 作为下一个示例,我们关闭流是不是一个好习惯? 问题答案: 通常根本不需要关闭流。您只需要关闭使用IO资源的流。 从Stream文档中: 流具有方法和实现,但是实际上几乎所有流实例在使用后都不需要关闭。通常,只有源是IO通道的流(例如由返回的)才需要关闭。大多数流都由集合,数组或生成函数支持,而无需特殊的资源管理。(如果流确实需

  • 如果我们使用Java8流,比如

  • 我想使用stream getfirst方法两次,但是出现了一个错误,即(java.lang.IllegalStateException:stream已经被操作或关闭),并且这个流代码以此处命名的注释开始。

  • 问题内容: 这是我目前拥有的代码: 一切都会按预期进行(调用writeToFile方法时将文件写入)。但是,当第二次调用writeToFile方法时,出现以下错误: 该文件仍按预期第二次写入,但是它将在第二次以及以后对writeToFile()的调用中引发此错误。我想知道是什么导致此错误发生。 问题答案: 写完后就在打电话。流关闭后,将无法再次写入。通常,实现此目标的方法是将结束状态移至write

  • 问题内容: 有人可以解释一下Java套接字中的以下行为: 总体思路是这样的: 打开套接字,获取I / O流。 写请求,关闭流 读取响应,关闭流 关闭插座。 这是我的问题。 如果我将a 用于输出,然后将其关闭,则它将关闭整个套接字,并且随后的读取操作将失败。 相反,如果我直接使用套接字的方法,它将正确关闭输出流通道,同时使套接字保持活动状态。 为什么关闭对象会使整个插槽都掉下来? 问题答案: 这可能