如何在 Java 中将 10 乘以“整数”对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to multiply 10 to an "Integer" object in Java?
提问by Jagmal
How do I multiply 10 to an Integer
object and get back the Integer
object?
如何将 10 乘以一个Integer
对象并取回该Integer
对象?
I am looking for the neatest way of doing this.
我正在寻找这样做的最简洁的方法。
I would probably do it this way:
Get int from Integer
object, multiply it with the other int and create another Integer object with this int value.
我可能会这样做:从Integer
对象中获取 int ,将其与另一个 int 相乘,然后使用此 int 值创建另一个 Integer 对象。
Code will be something like ...
代码将类似于...
integerObj = new Integer(integerObj.intValue() * 10);
But, I saw a code where the author is doing it this way: Get the String
from the Integer
object, concatenate "0" at the end and then get Integer
object back by using Integer.parseInt
但是,我看到了一个代码,作者是这样做的:String
从Integer
对象中获取,最后连接“0”,然后Integer
使用Integer.parseInt
The code is something like this:
代码是这样的:
String s = integerObj + "0";
integerObj = Integer.parseInt(s);
Is there any merit in doing it either way?
这样做有什么好处吗?
And what would be the most efficient/neatest way in general and in this case?
一般来说,在这种情况下,最有效/最简洁的方法是什么?
采纳答案by toolkit
With Java 5's autoboxing, you can simply do:
使用 Java 5 的自动装箱,您可以简单地执行以下操作:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);
回答by Matt Sheppard
The string approach is amusing, but almost certainly a bad way to do it.
字符串方法很有趣,但几乎肯定是一种糟糕的方法。
Getting the int value of an Integer, and creating a new one will be very fast, where as parseInt would be fairly expensive to call.
获取 Integer 的 int 值并创建一个新值将非常快,而 parseInt 调用起来相当昂贵。
Overall, I'd agree with your original approach (which, as others have pointed out, can be done without so much clutter if you have autoboxing as introduced in Java 5).
总体而言,我同意您的原始方法(正如其他人所指出的,如果您使用 Java 5 中引入的自动装箱,则可以在没有太多混乱的情况下完成)。
回答by Galbrezu
Keep away from the second approach, best bet would be the autoboxing if you're using java 1.5, anything earlier your first example would be best.
远离第二种方法,如果您使用的是 java 1.5,最好的选择是自动装箱,任何早期的第一个示例都是最好的。
回答by Clokey
The solution using the String method is not so good for a variety of reasons. Some are aesthetic reasons others are practical.
由于各种原因,使用 String 方法的解决方案并不是那么好。有些是审美原因,有些则是实用的。
On a practical front more objects get created by the String version than the more normal form (as you have expressed in your first example).
在实际方面,String 版本创建的对象比更普通的形式创建的对象更多(正如您在第一个示例中所表达的那样)。
On an aesthetic note, I think that the second version obscures the intent of the code and that is nearly as important as getting it to produce the result you want.
在美学方面,我认为第二个版本掩盖了代码的意图,这几乎与让它产生你想要的结果一样重要。
回答by ckpwong
The problem with the second way is the way Strings are handled in Java:
第二种方式的问题是在 Java 中处理字符串的方式:
"0"
is converted into a constant String object at compile time.Each time this code is called,
s
is constructed as a new String object, andjavac
converts that code toString s = new StringBuilder().append(integerObj.toString()).append("0").toString()
(StringBuffer for older versions). Even if you use the sameintegerObj
, i.e.,String s1 = integerObj + "0"; String s2 = integerObj + "0";
(s1 == s2)
would befalse
, whiles1.equals(s2)
would betrue
.Integer.parseInt
internally callsnew Integer()
anyway, becauseInteger
is immutable.
"0"
在编译时转换为常量 String 对象。每次调用此代码时,
s
都会将其构造为一个新的 String 对象,javac
并将该代码转换为String s = new StringBuilder().append(integerObj.toString()).append("0").toString()
(旧版本的 StringBuffer)。即使你使用相同的integerObj
,即,String s1 = integerObj + "0"; String s2 = integerObj + "0";
(s1 == s2)
会false
,而s1.equals(s2)
会true
。Integer.parseInt
内部调用new Integer()
无论如何,因为Integer
是不可变的。
BTW, autoboxing/unboxing is internally the same as the first method.
顺便说一句,自动装箱/拆箱在内部与第一种方法相同。
回答by Chris
toolkit's answer above is correct and the best way, but it doesn't give a full explanation of what is happening. Assuming Java 5 or later:
上面工具包的答案是正确的,也是最好的方法,但它没有对正在发生的事情给出完整的解释。假设 Java 5 或更高版本:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20
What you need to know is that this is the exact same as doing:
您需要知道的是,这与执行以下操作完全相同:
Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20
By performing the operation (in this case *=) on the object 'a', you are not changing the int value inside the 'a' object, but actually assigning a new object to 'a'. This is because 'a' gets auto-unboxed in order to perform the multiplication, and then the result of the multiplication gets auto-boxed and assigned to 'a'.
通过对对象“a”执行操作(在本例中为 *=),您不会更改“a”对象内的 int 值,而是实际将一个新对象分配给“a”。这是因为 'a' 被自动拆箱以执行乘法,然后乘法的结果被自动装箱并分配给 'a'。
Integer is an immutable object. (All wrapper classes are immutable.)
Integer 是一个不可变的对象。(所有包装类都是不可变的。)
Take for example this piece of code:
以这段代码为例:
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));
}
The output will be:
输出将是:
StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
You can see the memory address for 'i' is changing (your memory addresses will be different).
您可以看到“i”的内存地址正在更改(您的内存地址会有所不同)。
Now lets do a little test with reflection, add this onto the end of the test() method:
现在让我们用反射做一个小测试,将它添加到 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();
}
The additional output will be:
额外的输出将是:
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
You can see that the memory address for 'i' did not change, even though we changed its value using reflection.
(DO NOT USE REFLECTION THIS WAY IN REAL LIFE!!)
你可以看到 'i' 的内存地址没有改变,即使我们使用反射改变了它的值。
(不要在现实生活中以这种方式使用反射!!)