2008-09-05 1 views
8

Как я могу умножить 10 на объект Integer и вернуть объект Integer?Как умножить 10 на объект Integer в Java?

Я ищу самый аккуратный способ сделать это.

Я бы сделал это так: Получите int от объекта Integer, умножьте его на другой int и создайте еще один объект Integer с этим значением int.

Код будет что-то вроде ...

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

Но я видел код, где автор делает это таким образом: Получить String от Integer объекта, сцепить «0» в конце и затем получить Integer объект обратно с помощью Integer.parseInt

код что-то вроде этого:

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

ли Какая-либо заслуга в этом?

И что было бы самым эффективным/опрятным способом в целом и в этом случае?

+0

Я также советую вам проверить, действительно ли используется Integer. Джошуа указал, что использование примитивов в МЕНЬШЕ МНОГИЕ быстрее в Эффективной Java. Итак, если вы можете, придерживайтесь ** int **. – 2008-09-05 15:54:56

+0

Использование Integer на самом деле является конструктивным ограничением. Идея заключается в том, что я получаю объект Integer, и я должен его обновить. Итак, не могу покончить с этим :) – Jagmal 2008-09-05 17:40:24

+0

Обновление существующего объекта Integer не произойдет без отражения вуду. (Целое число, как и другие типы примитивных оболочек, является неизменным.) Самое лучшее, что вы можете разумно сделать - и что любой здравомыслящий пример будет делать, - заменить его другим объектом. Это достаточно хорошо для большинства случаев, но означает, что `void modifyInteger (Integer i)` ничего не сделает. – cHao 2014-04-15 02:48:58

ответ

25

С Java 5-х autoboxing, вы можете просто сделать:

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

Строковый подход забавный, но почти наверняка это плохой способ сделать это.

Получение значения int целого числа и создание нового будет очень быстрым, когда parseInt будет довольно дорого обращаться.

В целом, я согласен с вашим оригинальным подходом (который, как указывали другие, может быть выполнен без большого количества беспорядков, если у вас есть автобоксинг, введенный в Java 5).

1

Беречь от второго подхода, лучше было бы Autoboxing, если вы используете Java 1.5, все, что раньше ваш первый пример будет лучше ,

1

Решение, использующее метод String, не так хорошо по ряду причин. Некоторые из них - эстетические причины, по которым другие практичны.

На практическом фронте больше объектов создается строковой версией, чем более обычная форма (как вы выразили в первом примере).

Что касается эстетической заметки, я думаю, что вторая версия скрывает намерение кода, и это почти так же важно, как получение результата для получения желаемого результата.

3

Проблема со вторым способом является способ строки обрабатываются в Java:

  • "0" преобразуется в постоянный объект Струнный во время компиляции.
  • Каждый раз, когда этот код вызывается, 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 внутренне такой же, как и первый метод.

0

Ответ инструментария выше, правильный и лучший способ, но он не дает полного объяснения того, что происходит. Предполагая 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', вы не изменяете значение int внутри объекта 'a', но фактически назначаете новый объект '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 

Вы можете увидеть адрес памяти для «Я» (адреса вашей памяти будут разными).

Теперь давайте сделаем небольшой тест с отражением, добавьте это в конец метода испытаний():

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» не изменился, хотя мы изменили его значение с помощью отражения.
(НЕ ИСПОЛЬЗУЙТЕ ОТРАЖЕНИЕ ЭТОТ ПУТЬ В РЕАЛЬНОЙ ЖИЗНИ !!)

Смежные вопросы