java.math.MutableBigInteger的用途是什么?

java.math.MutableBigInteger的用途是什么?,java,Java,java.math.MutableBigInteger仅在包内可用。它继承自java.lang.Object,只有一个子类(SignedMutableBigInteger)只能从包内部获得 /** * A class used to represent multiprecision integers that makes efficient * use of allocated space by allowing a number to occupy only part of * an a

java.math.MutableBigInteger
仅在包内可用。它继承自
java.lang.Object
,只有一个子类(
SignedMutableBigInteger
)只能从包内部获得

/**
 * A class used to represent multiprecision integers that makes efficient
 * use of allocated space by allowing a number to occupy only part of
 * an array so that the arrays do not have to be reallocated as often.
 * When performing an operation with many iterations the array used to
 * hold a number is only reallocated when necessary and does not have to
 * be the same size as the number it represents. A mutable number allows
 * calculations to occur on the same number without having to create
 * a new number for every step of the calculation as occurs with
 *  BigIntegers.
 *
 * @see BigInteger
 * @version 1.12, 12/19/03
 * @author Michael McCloskey
 * @since 1.3
 */

我猜MutableBigInteger在内部用于BigInteger繁重的计算,而频繁的重新分配会降低计算速度。我不知道为什么它不作为java.math的一部分导出。也许有些人不喜欢可变值类

要澄清“可变”:
标准BigInteger在其整个生命周期中有一个值,给定两个BigInteger引用“a”和“b”,“a+b”将始终生成具有相同值的新BigInteger。假设这个值是4


使用MutableBigInteger,“a+b”最初可能会产生4,但由于其他代码更改了“a”和“b”引用的对象的值(也称为变异),因此在将来的某个时候会产生8、16、32或任何其他数字。因此,Java中的大多数(可能全部)值类型(字符、短、长、整数、BigInteger、BigDecimal、浮点、双精度、甚至字符串)都是不可变的。

BigInteger的问题在于它是不可变的:换句话说,一旦有了BigInteger对象,就不能更改对象本身的值,只能将其替换为新对象

现在这通常是一件好事,因为它可以防止出现别名等等(你不希望你的“2+3”突然变成“2+5”,因为你程序中其他地方的“3”的用户将它改成了“5”)。但是,在内部,BigInteger使用数组来保存该值的组件。对于较大的数字,此数组可能相当大;比如说,一个代表无数个元素的大整数可能需要一个由一千个元素组成的数组

那么,当我想向这个大整数中添加一个时会发生什么呢?我们创建一个新的BigInteger,它将在它的内部创建一个包含1000个元素的新数组,将旧BigInteger的内部数组中的所有元素复制到新BigInteger的内部数组中,最后一个除外,并将最后一个元素的新版本增加1。(或者可能需要更新最后两个。)如果不需要旧值,它会释放旧的BigInteger,从而释放数组


这显然是相当低效的,如果你只是摆脱旧的价值观无论如何。因此,如果您有这样的操作,您可以改为使用MutableBigInteger,只需更改现有MutableBigInteger的内部数组中的最后一个元素即可增加该值。这要快得多!然而,它确实破坏了旧的价值观,正如我在上面指出的,这可能是有问题的。如果有人给你整数“3”,你可以期望它保持不变。如果有人给你一个可变的BigInteger,不要期望它以后是同一个数字

MutableBigInteger在java.math库中引用。如果安装了JDK,请检查JDK目录中src.zip的内容

您将看到BigInteger使用它:


MutableBigInteger是BigInteger使用的数学算法的封装。

感谢您的回答。也许问题应该是:“为什么它不是公共课?”。我认为这样的类可能非常有用,特别是对于循环变量。我相应地扩展了我的答案。基本上,它可能不可变,因为其他值类型也不可变。这是一个会议,真的。谢谢你的回答。你很好地描述了这门课的运作方式。但是您遗漏了一件事:类不是公共的(声明时没有或使用默认修饰符)。因此,它不能从包java.math外部获得。@c0d3x和Curt,在其他不可变类中创建不可变构造函数标志肯定没有错,反之亦然。这肯定会保护你的“3”。坦白说,我有点恼火,BigInteger变量没有可变的LongLong和类似的变量。我觉得这种一成不变的业务是一种笨拙的迂腐行为,在使用它和阅读使用它的代码时,都违反了最小惊奇法则。说真的,你们有谁看过一页吗?太恶心了。我见过成千上万行几乎没有不变性的代码。它叫哈斯克尔,非常棒。:-)老实说,使大部分数据不可变几乎总是有利于编程。然而,在整个系统中严重依赖可变性的系统中,试图引入不变性往往会变得尴尬。这不是一个真正的概念问题;这是一个应用不好的问题。当涉及到数字时,封装的问题往往会分解为两种心态之一。1.我们是在提取即时存储,还是2。我们是在抽象直接的事物本身。在我看来,拥有一成不变的数字没有什么帮助,所以我倾向于默认第一种心态。如果我们同时需要数字和(不可变)立即数的存储,那么以下习惯用法(当前无效)肯定没有问题:
biginger-fiveBI=new-biginger(5,biginger.immutable)请记住,数字存储一开始有哪些共同点?我们喜欢增加它们<代码>bigI.inc()
不可能。我们喜欢给它们添加新的内容<代码>bigI.add(17)不可能。(等等)我真的认为,在设计图书馆时,有时我们会让学术界胡作非为。
public BigInteger divide(BigInteger val) {
    MutableBigInteger q = new MutableBigInteger(),
                      r = new MutableBigInteger(),
                      a = new MutableBigInteger(this.mag),
                      b = new MutableBigInteger(val.mag);

    a.divide(b, q, r);
    return new BigInteger(q, this.signum * val.signum);
}