2015-09-08 36 views
2

我一直在阅读有关Java 8的内容,但尚未尝试过。所以,我试图用它做简单的数学运算。Java流:在Int流上执行多个数字操作的一个班轮

我试图找到的平均,总和,最大值,并使用从Java 8的新技术我想收集在打印出所有的数字第一列表的最小值,然后打印出平均值,求和,分,和最大。

以下是我有:

List<Integer> list = Arrays.asList(5,6,2,12,7,9,15,18,-1,-8); 
OptionalDouble average = list.stream().mapToInt(num -> num).average(); 
int sum = list.stream().mapToInt(num -> num).sum(); 
//sort the numbers, so that min and max are found in array 
int[] arr = list.stream().mapToInt(a -> {System.out.println(a); return a;}).sorted().toArray(); 
System.out.println("Average: " + average.getAsDouble()); 
System.out.println("Sum: " + sum); 
System.out.println("The minimum is: " + arr[0] + ", and maximum: " + arr[arr.length-1]); 

有没有办法用一个流启动,而不是把3个不同的数据流来做到这一点?是否有一种方法可以在单个流源上执行多个并行操作?

而且,如果我是让我从终端/主机进行操作的数字,而不是它已经在集合中存在。如果正确地记得Java 8 In Action描述的存储CollectionsStreams之间的差异作为Collections已经具有所有它们的元素之一,而Streams连续地从源,逐个元素得到他们的数据。因此,这与通过控制台逐个提供数字的用户类似。所以,我的第二个问题是,是否有可能使数据源一个流的System.in而不必进行从用户输入的第一List,然后转换该List到流?

+2

'mapToInt(一 - > {的System.out.println(A);返回;})' - 这是不推荐;更喜欢'peek(System.out :: println)'。 –

+0

@LouisWasserman当我需要使用元素执行某些操作时,是否也应该使用'peek()',但不需要将它沿着流传递?示例如果我想在数组中创建一个数字串:'StringJoiner nums = new StringJoiner(“,”,“提供的数字是:”,“。\ n”)',然后是stream:'list.stream ().peek(a - > nums.add(a.toString()))。mapToDouble(a - > a)。summaryStatistics();'OR还有更好的方法来使用流元素进行副操作吗? – Abdul

+1

请不要。为这样的事情使用适当的收集器。 –

回答

3

一旦您拥有IntStream,请致电summaryStatistics()以获取包含计数,总和,最小值,最大值和平均值的IntSummaryStatistics对象。

通常,您可以拨打collectIntStream对流数值执行您自己的自定义计算。传入提供计算初始状态的Supplier(例如总和为0)。传递ObjIntConsumer,将当前值处理为计算状态(例如,将值添加到总和中)。通过一个BiConsumer合并两个单独计算(用于并行计算)的结果(例如,两个总和相加并存储在第一个总和中)。

我知道的输入流转换为java.util.streams.Stream的没有内置的方式。最直接的方法是按照您的建议进行操作 - 从输入读取数据,将值存储在List中,然后使用Stream进行处理。这当然有效,但它就像是一个“完全屏障” - 在进一步处理之前,整个内容必须立即存储在内存中。

如果我创造的东西,将转换输入从InputStreamjava.util.streams.Stream,我想有某种ReaderScanner自定义实现的Spliterator.ofInt,这将读取并解析按需int值内。然后,您可以将此自定义Spliterator.ofInt的实例传递给StreamSupport.intStream以创建IntStream

+0

感谢您在第3段的建议。 – Abdul

+0

@rgettman此外,'summaryStatistics()'将解决这个特定的问题,但我仍然想知道是否有一种方法可以在一个流上执行多个并行操作,无论它是否正在更改流中的元素 – Abdul

+2

@Abdul I已经添加了关于使用您自己的'Supplier','ObjIntConsumer'和'BiConsumer'执行您自己的定制计算的'collect'的第二段。无论流是否平行,这都是有效的。 – rgettman