我是初学者。这可能是一个愚蠢的问题。
我有一大堆非常大的数字。我需要找到数组中所有这些数字的总和。我定义了一个BigInteger并将其初始化为零。现在我将遍历数组并将每个元素添加到此BigInteger。
BigInteger big = BigInteger.ZERO;
for(BigInteger b : array){
big.add(b);
}
没有编译错误,但big
值仍然为零,代码不起作用。所以,我检查了一下并学习了BigInteger add方法返回的总和。我修改了上面的代码。
big = big.add(b);
现在这很好用。
我的问题:那里到底发生了什么?为什么第一个代码没有更新big
值。
我可以将此BigInteger.add()
与collection.add()
赞赏更多见解。谢谢。
答案 0 :(得分:8)
为什么没有第一个代码更新大值。
BigInteger是不可变的,你不能更改它,只能更改一个String或任何原始包装器。
e.g。
String s = "Hello ";
s.concat("World"); // doesn't change anything.
s = s.concat("World"); // Updates 's'
我可以将此BigInteger.add()与collection.add()
进行比较
集合是可变的,但这个标量值不是。
使用可变对象在很大程度上是一种性能让步。如果你有一个集合,每次它会表现非常糟糕时需要一个完整的副本。
答案 1 :(得分:4)
这是方法
的JavaDocpublic BigInteger add(BigInteger val)
Returns a BigInteger whose value is (this + val).
Parameters:
val - value to be added to this BigInteger.
Returns:
this + val
这意味着它不是修改值,而是计算新值并返回它。当您执行big = big.add(b)
时,您正在运行该方法,获取结果值,并用它替换big的原始值。
考虑使用整数,x和y的等价物。
int x = 3;
int y = 4;
x + y; // At this point, x is still 3 - as you've not assigned the result of this calculation anywhere
x = x + y; // Now - x will be 7
答案 2 :(得分:2)
我的问题:那里到底发生了什么?为什么不是第一个 代码更新大值。
因为它的不可变的任意精度整数意味着它实际上不会改变原始的整数但是在你调用add
方法时创建一个新的。注意不可变表示创建Object
后,其状态无法更改。例如String
,Integer
,Float
等。
Integer i = new Integer(10);//State 1
i = new Integer(20);//State 2 but does not update state 1
big.add(b);
在添加后返回值,您需要将其存储在其他或相同的变量中。
查看add方法在这里做了什么,
public BigInteger add(BigInteger val) {
if (val.signum == 0)
return this;
if (signum == 0)
return val;
if (val.signum == signum)
return new BigInteger(add(mag, val.mag), signum);
int cmp = compareMagnitude(val);
if (cmp == 0)
return ZERO;
int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
: subtract(val.mag, mag));
resultMag = trustedStripLeadingZeroInts(resultMag);
//Here it's creating new Object
return new BigInteger(resultMag, cmp == signum ? 1 : -1);//<====
}
我可以将此BigInteger.add()与collection.add()
进行比较
这里说List.add
实际上会将元素添加到列表中,您可以更改该元素的值,并注意List.add
不会创建新元素,但它实际上会添加原始元素的引用。