문제

10에 1을 어떻게 곱하나요? 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, 즉.,

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

    (s1 == s2) 될 것이다 false, 하는 동안 s1.equals(s2) 될 것이다 true.

  • Integer.parseInt 내부적으로 호출 new Integer() 어쨌든 왜냐하면 Integer 불변이다.

그런데, autoboxing/unboxing은 내부적으로 첫 번째 방법과 동일합니다.

두 번째 접근 방식을 피하십시오. Java 1.5를 사용하는 경우 가장 좋은 방법은 자동 박싱이 될 것입니다. 첫 번째 예제보다 이전 버전이 가장 좋습니다.

String 메서드를 사용한 솔루션은 여러 가지 이유로 그다지 좋지 않습니다.일부는 미학적 이유이고 다른 일부는 실용적인 이유입니다.

실용적인 면에서 (첫 번째 예에서 표현한 것처럼) 일반적인 형식보다 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'가 자동으로 unboxing되고, 곱셈의 결과가 자동으로 boxing되어 '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