我有一些整数,我正在使用Arrays.stream(int arr[](.sum((添加这些整数。它以int形式返回截断的和,而实际的和更大,适合long。为什么流API通过截断只返回int而不返回long?
尝试使用小整数,如int myArray[]={1,5,8};int sum=数组.stream(myArray(.sum((;
工作良好。
但对于和导致长的较长整数不起作用。
下面的场景1运行良好,返回14
int myArray[] = { 1, 5, 8 };
int sum = Arrays.stream(myArray).sum();
而场景2将不起作用,因为总和将超过32位。它给出的总和为-105032716,而预期的为4189334580
int myArray[] = { 2094967290, 2094967290};
int sum = Arrays.stream(myArray).sum();
为了得到正确的总和,如果我这样做,我会得到预期的结果4189334580
long sum = 0L + 2094967290+2094967290;
System.out.println(sum);
这取决于开发人员。你知道该期待什么,你正在处理什么数据,更重要的是,你要测试它。在我看来,这与我们处理任何intOne + intTwo
可能溢出的方式没有什么不同。
如果您知道总和将超过int
范围,则切换到长流(感谢Carlos Heuberger为asLongStream()
而不是mapToLong(i -> i)
(:
long sum = Arrays.stream(myArray).asLongStream().sum();
您正在对int
(s((32位基元数据类型(求和。如果要long
,求和long
。这就是原始数学的工作原理。
int c = 2094967290 + 2094967290;
System.out.println(c);
与相同
System.out.println(2094967290 + 2094967290);
使用long
(s(
System.out.println(2094967290 + 2094967290L);
或者使用这样的流将在这里产生正确的结果
long sum = Arrays.stream(myArray).mapToLong(Long::valueOf).sum();
或(如评论中所指出的(
long sum = Arrays.stream(myArray).asLongStream().sum();
但是,long
也可能溢出(它是一种64位的基元数据类型(。对于任意精度,应使用BigInteger
。
BigInteger sum = Arrays.stream(myArray).mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ZERO, (a, b) -> a.add(b));