2012-07-23 21 views
7

Tôi nghĩ rằng null được phép cho một Set.
Vậy tại sao đoạn mã sau:Tôi không thể đặt một null trong một SortedSet?

SortedSet<Integer> set = new TreeSet<Integer>(); 
set.add(null); 
set.add(1); //--->Line indicated by exception 

Cung cấp cho các ngoại lệ sau đây?

ngoại lệ trong chủ đề java.lang.NullPointerException "chính" tại
java.lang.Integer.compareTo (Unknown Source) tại
java.lang.Integer.compareTo (Unknown Source) tại
java. util.TreeMap.put (Unknown Source) tại
java.util.TreeSet.add (Unknown Source)

Trả lời

16

Vâng, bạn có thể. Nhưng bạn sẽ phải cung cấp Comparator của riêng mình để xử lý trường hợp khi null được so sánh với bất kỳ nội dung nào khác trong bộ của bạn. Với việc đặt hàng tự nhiên được áp dụng, các đối tượng Java không biết cách so sánh chúng với null. Inversely, null không biết làm thế nào để so sánh chính nó với bất kỳ đối tượng như bạn không thể gọi null.compareTo(object).

Triển khai ví dụ về "an toàn không an toàn" Comparator có thể được tìm thấy trong thư viện apache commons-collections. Hãy xem NullComparator. Bạn có thể sử dụng nó như vậy:

// Unfortunately no support for Java generics yet, in commons-collections 
@SuppressWarnings("unchecked") 
SortedSet<Integer> set = new TreeSet<Integer>(new NullComparator()); 
set.add(null); 
set.add(1); 
+1

+1. Dễ dàng tiếp cận tốt nhất. –

+0

@Lukas Eder chúng ta có thể làm điều tương tự cho TreeMap không? Trong java 7 TreeMap & TreeSet cả hai được thay đổi (http://bugs.java.com/view_bug.do?bug_id=5045147). –

+0

@AashutoshShrivastava: Tôi nghĩ điều này nên được trả lời tốt nhất trong câu hỏi Stack Overflow mới. Hãy tạo một cái. –

5

API của TreeSet (http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html#add(E)) nói rằng add sẽ ném một NPE:

nếu các yếu tố quy định là null và bộ này sử dụng trật tự tự nhiên, hoặc so sánh của nó không cho phép các phần tử rỗng

vì vậy nếu bạn muốn lưu trữ null, bạn phải cung cấp một Bộ so sánh có thể xử lý điều này biết giá trị null so với 0 hoặc tất cả các giá trị khác.

+0

+1 để giải thích lý do tại sao nó không hoạt động và cách khắc phục. –

2

Thay vì tạo một Trình so sánh, bạn có thể tạo giá trị "rỗng" của riêng mình.

static final Integer NULL = Integer.MIN_VALUE; 

set.add(NULL): 
+2

Đây có thể là một cách tiếp cận không được chấp nhận, cho rằng tất cả các giá trị số nguyên đều có ý nghĩa. Nếu các số được sử dụng được giới hạn trong một phạm vi cụ thể, thì phương pháp này có thể chấp nhận được. –

+2

MIN_VALUE ít có khả năng hữu ích nhất vì có các thuộc tính lẻ như 'x == -x && x! = 0';) Không thường xuyên rằng mọi giá trị đơn'int' là cần thiết, nhưng nó sử dụng' Long' thay thế có thể là một lựa chọn. –

+0

Hah, tôi chưa bao giờ nghĩ về 'x == -x' cho' MIN_VALUE'. Điều đó khá đáng ngạc nhiên khi sự bổ sung của hai không phải là lĩnh vực chuyên môn chính của bạn ... –

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