如何将10乘以一个“1”;整数;Java中的对象?
如何将10乘以一个如何将10乘以一个“1”;整数;Java中的对象?,java,types,casting,Java,Types,Casting,如何将10乘以一个整数对象,然后返回整数对象 我正在寻找最整洁的方法 我可能会这样做: 从Integer对象中获取int,将其与其他int相乘,并使用此int值创建另一个Integer对象 代码将类似于 integerObj = new Integer(integerObj.intValue() * 10); 但是,我看到一段代码,作者是这样做的:从Integer对象获取String,在末尾连接“0”,然后使用Integer.parseInt返回Integer对象 代码如下所示: String
整数
对象,然后返回整数
对象
我正在寻找最整洁的方法
我可能会这样做:
从Integer
对象中获取int,将其与其他int相乘,并使用此int值创建另一个Integer对象
代码将类似于
integerObj = new Integer(integerObj.intValue() * 10);
但是,我看到一段代码,作者是这样做的:从Integer
对象获取String
,在末尾连接“0”,然后使用Integer.parseInt
返回Integer
对象
代码如下所示:
String s = integerObj + "0";
integerObj = Integer.parseInt(s);
这样做有什么好处吗
一般来说,在这种情况下,最有效/最整洁的方法是什么?字符串方法很有趣,但几乎肯定是一种不好的方法 获取整数的int值并创建一个新值将非常快,而调用as parseInt将非常昂贵 总的来说,我同意您最初的方法(正如其他人所指出的,如果您使用Java 5中引入的自动装箱,则可以在没有太多混乱的情况下完成此方法)。使用Java 5,您只需执行以下操作:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);
远离第二种方法,最好的选择是自动装箱如果您使用的是java 1.5,那么第一个示例之前的任何方法都是最好的。由于各种原因,使用String方法的解决方案不太好。有些是美学上的原因,有些是实用的 实际上,字符串版本创建的对象比普通形式创建的对象多(如第一个示例所示)
从美学角度讲,我认为第二个版本模糊了代码的意图,这几乎与让它产生您想要的结果一样重要。第二种方法的问题是Java处理字符串的方式:
在编译时转换为常量字符串对象“0”
- 每次调用此代码时,
被构造为一个新的字符串对象,并且s
将该代码转换为javac
(旧版本的StringBuffer)。即使您使用相同的String s=new StringBuilder().append(integerObj.toString()).append(“0”).toString()
,即integerObj
String s1=integerObj+“0”; 字符串s2=整数BJ+“0”代码>
将为(s1==s2)
,而false
将为s1.equals(s2)
true
内部调用Integer.parseInt
,因为newinteger()
是不可变的Integer
顺便说一句,自动装箱/取消装箱在内部与第一种方法相同。toolkit上面的答案是正确的,也是最好的方法,但它没有对发生的情况给出完整的解释。 假设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
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
您可以看到“i”的内存地址正在更改(您的内存地址将不同)
现在让我们用反射进行一个小测试,将其添加到test()方法的末尾:
额外的产出将是:
StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
您可以看到,“i”的内存地址没有更改,即使我们使用反射更改了它的值。(现实生活中不要以这种方式使用反射!!)不建议使用整数构造函数。使用自动装箱或valueOf()代替…
Integer。parseInt(…)
不必创建Integer对象,它直接与原语int
一起工作。我还建议您检查是否确实需要使用Integer。Joshua指出,在高效的Java中使用原语的速度要快很多倍。所以,如果可以,请坚持使用int。使用Integer实际上是一个设计约束。我的想法是得到一个整数对象,我必须更新它。因此,无法消除:)如果没有反射巫毒,更新现有的整数对象是不会发生的。(Integer和其他基本包装类型一样,是不可变的。)您可以合理地做的最好的事情——任何正常的示例都会做的事情——就是用另一个对象替换它。这对于大多数情况来说已经足够了,但意味着void modifyInteger(Integer i)
不会做任何有价值的事情。