2008-09-05 22 views
8

Làm cách nào để nhân 10 với đối tượng Integer và lấy lại đối tượng Integer?Làm thế nào để nhân 10 đến một đối tượng "Integer" trong Java?

Tôi đang tìm cách gọn gàng nhất để thực hiện việc này.

Tôi có thể làm theo cách này: Nhận int từ đối tượng Integer, nhân với int khác và tạo đối tượng Integer khác với giá trị int này.

Mã sẽ được cái gì như ...

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

Nhưng, tôi thấy một mã nơi tác giả đang làm nó theo cách này: Lấy String từ đối tượng Integer, nối "0" ở cuối và sau đó nhận được Integer đối tượng trở lại bằng cách sử dụng Integer.parseInt

mã này là một cái gì đó như thế này:

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

là lại bất kỳ công đức trong việc làm nó một trong hai cách?

Và điều gì sẽ là cách hiệu quả nhất/gọn gàng nhất nói chung và trong trường hợp này?

+0

Tôi cũng khuyên bạn nên kiểm tra xem có sử dụng Integer là REALLY cần thiết hay không. Joshua chỉ ra rằng việc sử dụng nguyên thủy nhanh hơn MANY MANY lần trong Java hiệu quả. Vì vậy, nếu bạn có thể, hãy gắn bó với ** int **. –

+0

Sử dụng Integer thực sự là một ràng buộc thiết kế. Ý tưởng là tôi nhận được một đối tượng Integer và tôi phải cập nhật điều đó. Vì vậy, không thể làm điều đó :) – Jagmal

+0

Cập nhật đối tượng Integer hiện tại sẽ không xảy ra mà không có sự phản chiếu voodoo. (Integer, giống như các kiểu trình bao bọc nguyên thủy khác, là không thay đổi.) Tốt nhất bạn có thể làm một cách hợp lý - và bất kỳ ví dụ sane nào sẽ làm - thay thế nó bằng một đối tượng khác. Đó là đủ tốt cho hầu hết các trường hợp, nhưng có nghĩa là 'void modifyInteger (Integer i)' sẽ không làm bất cứ điều gì đáng giá. – cHao

Trả lời

25

Với Java 5 của autoboxing, bạn chỉ có thể làm:

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

Sử dụng hàm tạo Integer không được khuyến cáo. Sử dụng autoboxing hoặc valueOf() thay vào đó ... –

7

Cách tiếp cận chuỗi là thú vị, nhưng gần như chắc chắn là một cách xấu để làm điều đó.

Lấy giá trị int của Số nguyên và tạo giá trị mới sẽ là rất nhanh, ở đâu như parseInt sẽ khá tốn kém để gọi. Nói chung, tôi đồng ý với phương pháp tiếp cận ban đầu của bạn (trong đó, như những người khác đã chỉ ra, có thể được thực hiện mà không có quá nhiều lộn xộn nếu bạn có autoboxing như được giới thiệu trong Java 5).

1

Tránh xa ra các cách tiếp cận thứ hai, đặt cược tốt nhất sẽ là autoboxing nếu bạn đang sử dụng java 1.5, bất cứ điều gì trước đó ví dụ đầu tiên của bạn sẽ là tốt nhất .

1

Giải pháp sử dụng phương pháp String không tốt cho nhiều lý do. Một số lý do thẩm mỹ khác là thực tế.

Trên mặt trước thực tế, nhiều đối tượng được tạo bởi phiên bản String so với biểu mẫu bình thường hơn (như bạn đã thể hiện trong ví dụ đầu tiên).

Trên một lưu ý thẩm mỹ, tôi nghĩ rằng phiên bản thứ hai che khuất ý định của mã và đó là gần như quan trọng như nhận được nó để tạo ra kết quả mà bạn muốn.

3

Vấn đề với cách thứ hai là cách Strings được xử lý trong Java:

  • "0" được chuyển thành một đối tượng String liên tục tại thời gian biên dịch.
  • Mỗi lần mã này được gọi, s được tạo làm đối tượng Chuỗi mới và javac chuyển mã đó thành String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer cho các phiên bản cũ hơn). Ngay cả khi bạn sử dụng cùng một integerObj, tức là,

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

    (s1 == s2) sẽ false, trong khi s1.equals(s2) sẽ true.

  • Integer.parseInt gọi nội bộ new Integer() dù sao, vì Integer là không thay đổi.

BTW, autoboxing/unboxing là nội bộ giống như phương pháp đầu tiên.

+0

'Integer.parseInt (...) 'không phải tạo một đối tượng Integer, nó trực tiếp làm việc với một nguyên tử' int'. –

0

câu trả lời của bộ công cụ ở trên là chính xác và tốt nhất, nhưng nó không giải thích đầy đủ về những gì đang xảy ra. Giả Java 5 hoặc mới hơn:

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

Những gì bạn cần phải biết là điều này là chính xác giống như thực hiện:

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

Bằng cách thực hiện các hoạt động (trong trường hợp này * =) trên đối tượng 'a', bạn không thay đổi giá trị int bên trong đối tượng 'a', nhưng thực sự gán một đối tượng mới cho 'a'. Điều này là do 'a' được tự động unboxed để thực hiện phép nhân, và sau đó kết quả của phép nhân được tự động đóng hộp và gán cho 'a'.

Số nguyên là một đối tượng bất biến. (Tất cả các lớp wrapper là không thay đổi.)

Đưa ví dụ đoạn mã này:

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)); 
} 

Kết quả sẽ là:

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

Bạn có thể xem địa chỉ bộ nhớ cho 'i' là thay đổi (địa chỉ bộ nhớ của bạn sẽ khác nhau).

Bây giờ cho phép làm một thử nghiệm nhỏ với suy nghĩ, thêm này vào phần cuối của bài kiểm tra() phương pháp:

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(); 
} 

Các công suất tăng thêm sẽ là:

MiddleMemory: 190331520 
Step2: 15 
MiddleMemory: 190331520 

Bạn có thể thấy rằng địa chỉ bộ nhớ cho 'i' không thay đổi, mặc dù chúng tôi đã thay đổi giá trị của nó bằng cách sử dụng sự phản chiếu.
(KHÔNG SỬ DỤNG LỰA CHỌN CÁCH NÀY TRONG CUỘC SỐNG THỰC HIỆN !!)

Các vấn đề liên quan