2012-07-23 59 views
7

我认为null被允许的Set
那么,为什么下面的代码:我不能在SortedSet中放置null吗?

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

给出了下面的异常?

在线程 “主” 显示java.lang.NullPointerException处
java.lang.Integer.compareTo(未知来源)
java.lang.Integer.compareTo(未知来源)在
Java异常。 util.TreeMap.put(来源不明)在
java.util.TreeSet.add(来源不明)

回答

16

是的,可以。但你必须提供自己的Comparatornull进行比较,您所设定的其他任何内容,处理的情况。随着自然顺序的应用,Java对象不知道如何将自己与null进行比较。相反,null不知道如何与任何对象进行比较,因为您无法拨打null.compareTo(object)

这种“无效安全”Comparator的示例实现可以在apache commons-collections库中找到。检查出NullComparator。你可以使用它作为这样的:

// 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。轻松采用最佳方法。 – 2012-07-23 07:55:08

+0

@Lukas Eder我们可以为TreeMap做同样的事吗?在java 7中,TreeMap和TreeSet都发生了变化(http://bugs.java.com/view_bug.do?bug_id=5045147)。 – 2014-10-01 08:31:58

+0

@AashutoshShrivastava:我认为这应该是最好的答案在一个新的堆栈溢出问题。随意创建一个。 – 2014-10-01 17:45:06

5

TreeSet的(http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html#add(E))的API表示,加将抛出NPE:

如果指定的元素为null,并且此set使用自然顺序, 或它的比较器不允许空元素

所以如果你想存储null,你必须提供一个比较器,它可以处理这个知道空位与0或所有其他值相比的位置。

+0

+1解释为什么它不工作,以及如何解决它。 – 2012-07-23 07:55:34

2

而是创造一个比较,你可以创建自己的“空”的价值。

static final Integer NULL = Integer.MIN_VALUE; 

set.add(NULL): 
+2

考虑到所有整数值都有含义,这可能是一种不可接受的方法。如果使用的数字限制在特定的范围内,则此方法可能是可以接受的。 – 2012-07-23 07:54:32

+2

MIN_VALUE是最不可能有用的,因为像'x == -x && x!= 0'这样的奇特属性;)通常不需要每个'int'值,但它使用的是Long可能是一个选择。 – 2012-07-23 08:01:48

+0

哈,我从来没有想过'MIN_VALUE'的'x == -x'。当二进制补码不是您的主要专业领域时,这非常令人吃惊...... – 2012-07-23 08:04:20