2009-06-04 39 views
26

Tôi là người lập trình Java mới và tôi chỉ đọc một biến của một lớp số nguyên có thể được mô tả theo ba cách khác nhau trong API. Tôi có mã sau:So sánh giá trị số nguyên

if (count.compareTo(0)) { 
      System.out.println(out_table); 
      count++; 
    } 

Đây là một vòng lặp và chỉ xuất ra out_table.
Mục tiêu của tôi là tìm hiểu cách xem giá trị trong số nguyên count > 0.

Tôi nhận ra rằng count.compare(0) là cách chính xác? hoặc là nó count.equals(0)?

Tôi biết số count == 0 không chính xác. Thê nay đung không? Có một toán tử so sánh giá trị ở đó chỉ count=0 của nó không?

Trả lời

25

Số nguyên được autounboxed, vì vậy bạn chỉ có thể làm

if (count > 0) { 
    .... 
} 
+5

Lỗi tương tự như luật sư. Đây là autounboxing. –

+0

vâng, tệ của tôi. cố định điều đó. –

+1

Ummm. Không hẳn. ... Trong các so sánh khác, điều này không phải luôn luôn như vậy. Điều gì nếu bạn đang so sánh hai số nguyên và sử dụng '=='? Sau đó, các cá thể được so sánh, nhưng đôi khi JVM không lưu trữ chúng để nó báo cáo các giá trị giống hệt nhau. Xem http://stackoverflow.com/questions/10002037/comparing-integer-values-in-java-strange-behavior. – ingyhere

29

Để tìm hiểu xem một Integer là lớn hơn 0, bạn có thể:

  • kiểm tra nếu compareTo(O) trả về một số nguyên dương:

    if (count.compareTo(0) > 0) 
        ... 
    

    Nhưng điều đó có vẻ khá ngớ ngẩn, đúng không ? Better chỉ ...

  • sử dụng autoboxing :

    if (count > 0) 
        .... 
    

    này tương đương với:

    if (count.intValue() > 0) 
        ... 
    

    Điều quan trọng cần lưu ý là "==" được đánh giá như thế này, với các toán hạng Integer không được mở hộp chứ không phải là toán hạng int. Nếu không, count == 0 sẽ trả về false khi count được khởi tạo là new Integer(0) (vì "==" kiểm tra tính bình đẳng tham chiếu).

Về mặt kỹ thuật, ví dụ đầu tiên sử dụng autoboxing (trước Java 1.5 bạn không thể vượt qua một int để compareTo) và ví dụ thứ hai sử dụng unboxing. Tính năng kết hợp thường được gọi đơn giản là "autoboxing" cho ngắn, thường được mở rộng thành gọi cả hai loại chuyển đổi "autoboxing". Tôi xin lỗi vì đã sử dụng thuật ngữ lỏng lẻo của tôi.

+1

Ví dụ trước đây đang sử dụng autoboxing; autounboxing thứ hai. –

+4

+1: Về sự so sánh '== ', người ta phải rất thận trọng khi so sánh * hai * * đóng hộp * số (nhưng không phải một hộp và một số nguyên thủy), bởi vì, như mmyers đã đề cập,' == 'kiểm tra để tham khảo bình đẳng, không bình đẳng của các giá trị bọc. –

3

Mặc dù bạn chắc chắn có thể sử dụng phương pháp compareTo trên một thể hiện Integer, nó không phải là rõ ràng khi đọc mã, vì vậy có lẽ bạn nên tránh làm như vậy.

Java cho phép bạn sử dụng autoboxing (xem http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html) để so sánh trực tiếp với một int, vì vậy bạn có thể làm:

if (count > 0) { } 

Integer dụ count được tự động chuyển đổi thành một int cho việc so sánh.

Nếu bạn gặp sự cố sự hiểu biết này, hãy kiểm tra các liên kết ở trên, hoặc tưởng tượng nó làm điều này:

if (count.intValue() > 0) { } 
+0

bỏ phiếu cho các liên kết thông tin. Hãy nhớ rằng 'số' phải không rỗng. Ngoại lệ được tạo ra tại thời gian chạy tự động unboxing một giá trị null là khó hiểu. – Chadwick

13

Nó tốt hơn để tránh autoboxing không cần thiết cho 2 lý do.

Đối với một điều, nó chậm hơn một chút so với int < int, vì bạn (đôi khi) tạo một đối tượng phụ;

void doSomethingWith(Integer integerObject){ ... 
    int i = 1000; 
    doSomethingWith(i);//gets compiled into doSomethingWith(Integer.valueOf(i)); 

Vấn đề lớn hơn là autoboxing ẩn có thể ẩn trường hợp ngoại lệ:

void doSomethingWith (Integer count){ 
    if (count>0) // gets compiled into count.intValue()>0 

gọi method này với null sẽ ném một NullPointerException.

Sự phân chia giữa các đối tượng nguyên thủy và trình bao bọc trong java luôn được mô tả là một kludge cho tốc độ. Tự động ẩn gần như ẩn, nhưng không hoàn toàn - nó sạch hơn chỉ để theo dõi loại. Vì vậy, nếu bạn đã có một đối tượng Integer, bạn chỉ có thể gọi compare() hoặc intValue(), và nếu bạn đã có nguyên thủy chỉ cần kiểm tra giá trị trực tiếp.

+0

+1 Để đề cập đến các mặt phủ định của hộp tự động. Sự khác biệt hiệu suất có thể rất lớn, đặc biệt là khi auto (un) boxing trong vòng lặp. – helpermethod

12

Bạn cũng có thể sử dụng tương đương với:

Integer a = 0; 

if (a.equals(0)) { 
    // a == 0 
} 

tương đương với:

if (a.intValue() == 0) { 
    // a == 0 
} 

và cũng:

if (a == 0) { 

} 

(trình biên dịch Java sẽ tự động thêm intValue())

Lưu ý rằng autoboxing/autounboxing có thể giới thiệu một chi phí đáng kể (đặc biệt là các vòng lặp bên trong).

+0

0.equals (a) không biên dịch. Hay bạn đang nói không sử dụng nó? –

+0

cố định, nhờ :-) – dfa

1

Một điều nữa cần lưu ý là nếu giá trị thứ hai là một đối tượng Integer khác thay cho chữ '0', toán tử '==' so sánh con trỏ đối tượng và sẽ không tự động bỏ hộp.

ví dụ:

Integer a = new Integer(0); 
Integer b = new Integer(0); 
int c = 0; 

boolean isSame_EqOperator = (a==b); //false! 
boolean isSame_EqMethod = (a.equals(b)); //true 
boolean isSame_EqAutoUnbox = ((a==c) && (a.equals(c)); //also true, because of auto-unbox 

//Note: for initializing a and b, the Integer constructor 
// is called explicitly to avoid integer object caching 
// for the purpose of the example. 
// Calling it explicitly ensures each integer is created 
// as a separate object as intended. 
// Edited in response to comment by @nolith 
+0

Bạn phải khởi tạo 'a' và' b' bằng 'Số nguyên mới (0)' nếu không 'isSame_EqOperator' sẽ là' true' – nolith

+0

Goodpoint @nolith, mặc dù điều này là do bộ nhớ đệm của các số nguyên trong Java , giải thích tốt trong câu trả lời được chấp nhận cho http://stackoverflow.com/questions/3131136/integers-caching-in-java. Tôi sẽ thay đổi câu trả lời của tôi để sử dụng chỉnh sửa được đề xuất của bạn với nhận xét mô tả lý do sử dụng rõ ràng hàm tạo. – Sogger

0

tôi cũng có thể bị trễ về vấn đề này nhưng tôi muốn chia sẻ điều gì đó:

Với đầu vào: System.out.println (isGreaterThanZero (-1));

public static boolean isGreaterThanZero(Integer value) { 
    return value == null?false:value.compareTo(0) > 0; 
} 

Returns sai

public static boolean isGreaterThanZero(Integer value) { 
    return value == null?false:value.intValue() > 0; 
} 

Returns đúng Vì vậy, tôi nghĩ rằng trong yourcase 'compareTo' sẽ chính xác hơn.

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