Java streams:一个对Int流执行多个数值操作的线性程序

Java streams:一个对Int流执行多个数值操作的线性程序,java,lambda,stream,java-8,java-stream,Java,Lambda,Stream,Java 8,Java Stream,我一直在阅读Java8,但还没有尝试过。所以,我试图用它做简单的数学运算 我正在尝试使用Java8中的新技术查找列表的平均值、总和、最大值和最小值。我想先打印集合中的所有数字,然后打印平均值、总和、最小值和最大值 以下是我所拥有的: List<Integer> list = Arrays.asList(5,6,2,12,7,9,15,18,-1,-8); OptionalDouble average = list.stream().mapToInt(num -> num).av

我一直在阅读Java8,但还没有尝试过。所以,我试图用它做简单的数学运算

我正在尝试使用Java8中的新技术查找列表的平均值、总和、最大值和最小值。我想先打印集合中的所有数字,然后打印平均值、总和、最小值和最大值

以下是我所拥有的:

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]);
List 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();
//对数字进行排序,以便在数组中找到最小值和最大值
int[]arr=list.stream().mapToInt(a->{System.out.println(a);返回a;}).sorted().toArray();
System.out.println(“Average:+Average.getAsDouble());
System.out.println(“总和:+Sum”);
System.out.println(“最小值为:“+arr[0]+”,最大值为:“+arr[arr.length-1”);
有没有一种方法可以通过一个流启动而不是生成3个不同的流来实现这一点?有没有一种方法可以在单个流源上执行多个并行操作


另外,如果我要从终端/控制台获取我正在执行操作的数字,而不是已经在一个集合中,该怎么办。如果我没记错的话,
java8-In-Action
集合
之间的一个区别描述为
集合
已经存储了所有元素,而
不断地从源代码中逐个元素获取数据。因此,这类似于用户通过控制台逐个提供数字。因此,我的第二个问题是,是否可以将流的数据源设置为
系统。在
中,不必首先从用户输入中设置
列表,然后将该
列表转换为流?

一旦设置了
IntStream
,调用以获取包含计数、总和、最小值、最大值和平均值的
IntSummaryStatistics
对象

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

我知道没有内置的方法将输入流转换为
java.util.streams.stream
。最直接的方法是按照您已经建议的方式执行—从输入中读取,将值存储在
列表中
,然后使用
对其进行处理。这当然是可行的,但它就像一个“完整的屏障”——在进行进一步的处理之前,整个内容必须立即存储在内存中


如果我要创建一些东西,将输入从
InputStream
转换为
java.util.streams.Stream
,我将在
拆分器ofInt
的自定义实现中使用某种
读取器或
扫描仪
,它将根据需要读取和解析
int
值。然后,您可以传递此自定义的
拆分器的一个实例。OFIT
来创建
IntStream

,感谢第3段中的建议。@rgetman另外,
summaryStatistics()
将解决此特定问题,但我仍然想知道是否有办法在一个流上执行多个并行操作,是否正在更改流中的元素或not@Abdul我已经添加了第二段关于使用自己的
供应商
ObjIntConsumer
和执行自定义计算的
双消费者
实现调用
收集
。无论流是否并行,这都是有效的。@Abdul它应该是这样的:
new BufferedReader(System.console().reader()).lines().mapToInt(Integer::parseInt).
如果用户输入数字,每行一个,这将给您一个
IntStream
@erickson,您应该添加它作为另一个答案,因为这是对原始问题的一部分的回答。(在看到您的评论之前,我一直在考虑这样做。)
mapToInt(a->{System.out.println(a);返回a;})
——不建议这样做;更喜欢
peek(System.out::println)
@LouisWasserman当我需要使用元素执行某些操作,但不需要沿着流传递时,我是否也应该使用
peek()
?例如,若我想在数组中创建一个数字字符串:
StringJoiner nums=newstringjoiner(“,”,“提供的数字是:”,“\n”)
,然后是流:
list.stream().peek(a->nums.add(a.toString()).mapToDouble(a->a.summaryStatistics()或者是否有更好的方法使用流元素执行附加操作?请不要这样做。使用合适的收集器来收集类似的东西。这就是为什么我不应该像@LouisWasserman所说的那样使用
peek()