Sio*_*733 6 java java-8 java-stream
我正在测试java-8中的新Stream
API,并想检查10000随机coinflips的结果.到目前为止,我有:
public static void main(String[] args) {
Random r = new Random();
IntStream randomStream = r.ints(10000,0, 2);
System.out.println("Heads: " + randomStream.filter(x -> x==1).count());
System.out.println("Tails: " + randomStream.filter(x -> x==0).count());
}
Run Code Online (Sandbox Code Playgroud)
但这引发了异常:
java.lang.IllegalStateException: stream has already been operated upon or closed
Run Code Online (Sandbox Code Playgroud)
我理解为什么会发生这种情况,但如果我只能使用一次流,我该如何打印头尾的计数呢?
第一种解决方案依赖于这样一个事实,即按照二项式法则计算10 000个硬币翻转的头尾数.
对于此特定用例,您可以使用该summaryStatistics
方法.
Random r = new Random();
IntStream randomStream = r.ints(10000,0, 2);
IntSummaryStatistics stats = randomStream.summaryStatistics();
System.out.println("Heads: "+ stats.getSum());
System.out.println("Tails: "+(stats.getCount()-stats.getSum()));
Run Code Online (Sandbox Code Playgroud)
collect
操作创建一个映射,该映射将映射每个可能的结果及其在流中的出现次数.
Map<Integer, Integer> map = randomStream
.collect(HashMap::new,
(m, key) -> m.merge(key, 1, Integer::sum),
Map::putAll);
System.out.println(map); //{0=4976, 1=5024}
Run Code Online (Sandbox Code Playgroud)
最后一个解决方案的优点是,这适用于您为要生成的随机整数提供的任何边界.
例:
IntStream randomStream = r.ints(10000,0, 5);
....
map => {0=1991, 1=1961, 2=2048, 3=1985, 4=2015}
Run Code Online (Sandbox Code Playgroud)
虽然所有其他答案都是正确的,但它们的表述有点麻烦。
Map<Integer, Long>
, 将翻转的硬币映射到计数。
Map<Integer, Long> coinCount = new Random().ints(10000, 0, 2)
.boxed()
.collect(Collectors.groupingBy(i -> i, Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)
这将首先创建IntStream
,然后Stream<Integer>
将它们装箱到,因为在此示例中无论如何您都将它们存储在其装箱版本中。最后用一个groupingBy
关于身份的函数收集它们i -> i
,它给你一个Map<Integer, List<Integer>>
,这不是你想要的,因此你用对它List<Integer>
的操作替换了Collectors.counting()
,这样List<Integer>
就变成了Long
,从而产生了Map<Integer, Long>
。
归档时间: |
|
查看次数: |
207 次 |
最近记录: |