如何将 10 乘以一个 Integer 对象并取回 Integer 目的?

我正在寻找最简洁的方法来做到这一点。

我可能会这样做:获取整数来自 Integer 对象,将其与另一个 int 相乘,并使用该 int 值创建另一个 Integer 对象。

代码将类似于...

integerObj = new Integer(integerObj.intValue() * 10);

但是,我看到作者这样做的代码:获取 String 来自 Integer 对象,在末尾连接“0”,然后得到 Integer 通过使用返回对象 Integer.parseInt

代码是这样的:

String s = integerObj + "0";
integerObj = Integer.parseInt(s);

这样做有什么好处吗?

在这种情况下,一般情况下最有效/最简洁的方法是什么?

有帮助吗?

解决方案

使用 Java 5 自动装箱, ,您可以简单地执行以下操作:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);

其他提示

字符串方法很有趣,但几乎可以肯定是一种糟糕的方法。

获取 Integer 的 int 值并创建一个新的值将非常快,而调用 parseInt 的成本相当昂贵。

总的来说,我同意你原来的方法(正如其他人指出的那样,如果你有 Java 5 中引入的自动装箱功能,那么可以在没有太多混乱的情况下完成)。

第二种方式的问题在于 Java 中处理字符串的方式:

  • "0" 在编译时转换为常量 String 对象。
  • 每次调用此代码时, s 被构造为一个新的 String 对象,并且 javac 将该代码转换为 String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (旧版本的 StringBuffer)。即使你使用相同的 integerObj, , IE。,

    String s1 = integerObj + "0"; String s2 = integerObj + "0";

    (s1 == s2) 将会 false, , 尽管 s1.equals(s2) 将会 true.

  • Integer.parseInt 内部调用 new Integer() 无论如何,因为 Integer 是不可变的。

顺便说一句,自动装箱/拆箱在内部与第一种方法相同。

远离第二种方法,如果您使用的是 java 1.5,最好的选择是自动装箱,任何早期的第一个示例都是最好的。

由于多种原因,使用 String 方法的解决方案并不是那么好。有些是出于美观原因,有些则是实用原因。

在实际方面,字符串版本比更普通的形式创建更多的对象(正如您在第一个示例中所表达的那样)。

从美学角度来看,我认为第二个版本掩盖了代码的意图,这几乎与让它产生您想要的结果一样重要。

工具包上面的答案是正确的,也是最好的方法,但它没有给出正在发生的事情的完整解释。假设 Java 5 或更高版本:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20

您需要知道的是,这与执行以下操作完全相同:

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20

通过对对象“a”执行操作(在本例中为 *=),您并没有更改“a”对象内部的 int 值,而是实际上将一个新对象分配给“a”。这是因为“a”会自动拆箱以便执行乘法,然后乘法的结果会自动装箱并分配给“a”。

整数是一个不可变的对象。(所有包装类都是不可变的。)

以这段代码为例:

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}

输出将是:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520

您可以看到“i”的内存地址正在改变(您的内存地址将会不同)。

现在让我们用反射做一个小测试,将其添加到 test() 方法的末尾:

System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
    final Field f = i.getClass().getDeclaredField("value");
    f.setAccessible(true);
    f.setInt(i, 15);
    System.out.println("Step3: " + i.intValue());
    System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
    e.printStackTrace();
}

额外的输出将是:

MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520

您可以看到“i”的内存地址没有改变,即使我们使用反射更改了它的值。
(不要在现实生活中以这种方式使用反射!!)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top