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

Java Lambda re-use Stream

万俟玉书
2023-03-14

我想尝试lambdas的一些功能,并希望编写过滤器ArrayList并使用IntStream的方法计算数组列表的平均值和最大值。

我的第一个想法是过滤ArrayList,保存流,然后使用方法计算:

ArrayList<Integer> arr = new ArrayList<>();
arr.add(5);
arr.add(7);
arr.add(11);

IntStream s = arr.stream().filter(i -> i < 10).mapToInt(i -> (int)i);
int maxBelowTen = s.max().getAsInt();
double avgBelowTen = s.average().getAsDouble();
System.out.println("Maximum below ten: " + maxBelowTen);
System.out.println("Average below ten: " + avgBelowTen);

但是,这将引发Java . lang . illegalstateexception:stream已经被操作或关闭

有了这些信息,我当然把它带到工作中,打开两个流,过滤两次

int maxBelowTen = arr.stream().filter(i -> i < 10).mapToInt(i -> (int) i).max().getAsInt();
double avgBelowTen = arr.stream().filter(i -> i < 10).mapToInt(i -> (int) i).average().getAsDouble();

但我现在的问题是关于性能。如果我必须过滤和映射流两次,这不是很慢吗。为什么我不能在一个流上操作不止一次,我不明白他们为什么这样实现它。因为每个操作符方法都返回一个新的流或一个值,所以在一个操作之后,不可能让流保持打开状态吗。

这是什么原因,或者我只是用错了?

共有2个答案

丁宏浚
2023-03-14

如果您想“保存”中间流操作的结果,您可以这样做;您只需要显式地这样做:您必须执行arr.stream(). filter(i-

流不是数据结构,它们是尚未运行的未决计算,可能会以非标准方式将未来的操作合并在一起。如果您想将中间结果存储在适当的数据结构中,您必须自己动手。

屠兴旺
2023-03-14

如果你用一种很好的老方法,通过使用一个循环,你会用一个循环计算最大元素和平均值。所以你只需要在这里做同样的事情。幸运的是,流API可以为您做到这一点:

IntStream s = arr.stream().mapToInt(i -> Integer::intValue).filter(i < 10);
IntSummaryStatistics stats = s.summaryStatistics();

double average = stats.getAverage();
int max = stats.getMax();

阅读IntSummary统计的javadoc应该可以帮助您了解如何自己实现这样的操作。

 类似资料:

相关问答

相关文章

相关阅读