【问题标题】:Java 8 Stream illegal exceptionJava 8 Stream 非法异常
【发布时间】:2020-05-07 12:13:22
【问题描述】:

==============更新==============: 实际上,我将流作为我方法的参数,我无法改变它。而且我必须处理三次。

MyAggregate aggregate(Stream<IncomingProduct> products){
        Supplier<Stream<IncomingProduct>> streamSupplier
                = () -> products;
        if(streamSupplier.get() == null || !streamSupplier.get().findAny().isPresent()){
            return null;
        }
        List<MyProduct> myProducts = streamSupplier.get()
                .map(p -> new MyProduct(p.getName(), p.getPrice()))
                .collect(Collectors.toList());
        BigDecimal price = myProducts.stream()
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return new MyAggregate(myProducts,price);
    }
}

我遇到了以下异常: 线程“main”java.lang.IllegalStateException 中的异常:流已被操作或关闭

【问题讨论】:

  • 你不能消费一个流两次。
  • 无论“对象名称”应该是什么,都没有区别。还是一样的错误,供应商() -&gt; products总是返回相同的Stream对象。
  • 没什么。只需删除此声明以及随后的 if 声明即可。只需使用List&lt;MyProduct&gt; myProducts = products .map(p -&gt; new MyProduct(p.getName(), p.getPrice())) .collect(Collectors.toList());
  • 您的代码中没有“某些处理”。只有一个有问题的null 处理(当参数为null 时返回null)和一个更糟糕的行为(当流为空时返回null)没有任何必要。只需执行 collect 操作将为您提供一个空流的空结果列表,这是合理的。如果在那种情况下你仍然需要做一个特殊的操作,那仍然是可能的。如果您坚持有问题的null 处理,if(products == null) return null; 将起作用。
  • 如前所述,if(products == null) return null; 可以工作,即使不推荐编码风格。另外,如前所述,当您使用空流执行List&lt;MyProduct&gt; myProducts = products .map(p -&gt; new MyProduct(p.getName(), p.getPrice())) .collect(Collectors.toList()); 时,不会有任何问题,它只会评估为一个空列表,因此在出现空流的情况下您想做的任何事情都可以在那之后完成,就像if(myProducts.isEmpty()) { /* your special action */ } 一样简单。

标签: java java-8 java-stream


【解决方案1】:

您不能两次消费流。您的供应商需要重新创建它:

    Supplier<Stream<SoldProduct>> streamSupplier
            = () -> Stream.of(s1,s2,s3);

【讨论】:

    【解决方案2】:

    一旦通过任何操作(如 map、filter 或任何其他终端操作(如 collect、anymatch 等)访问流),您就不能像这样使用流两次。那么你不能再次使用它你必须将产品存储在列表中,然后使用 list.stream() 以便为这两个操作创建新流

     List<SoldProduct> products = List.of(s1,s2,s3);
     Supplier<List<SoldProduct>> listSupplier
                    = () -> products;
     listSupplier.get().stream().anyMatch(s -> true);
     listSupplier.get().stream().anyMatch(s -> true);
    

    【讨论】:

    • 或者,将其保留为Supplier&lt;SoldProduct&gt;,并使用() -&gt; products.stream()
    猜你喜欢
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    相关资源
    最近更新 更多