首先在Java 1.7中的TreeSet上添加调用compareTo
我有一个TreeSet元素,并根据:
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html#compareTo%28T%29
[当且仅当e1.compareTo(e2)== 0与e1.equals(e2)具有相同的布尔值时,类C的自然顺序被认为与等于一致。对于类C的每个e1和e2 null不是任何类的实例, 即使e.equals(null)返回false , e.compareTo(null)也应抛出NullPointerException。 ]
Element类具有非空安全的compareTo方法
我有以下代码在Java 1.5上工作,但不在Java 1.7中
@Test
public void simpleTest() {
try {
Collection<Element> set = new TreeSet<Element>();
Element cv = new Element(null);
set.add(cv);//first add throws NPE (calling to compareTo())
} catch (Exception e) {
e.printStackTrace();
}
}
private class Element implements Comparable<Element> {
private final String attr;
public Element(String attr) {
super();
this.attr = attr;
}
@Override
public int hashCode() {
System.out.println("executing hashCode...");
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((attr == null) ? 0 : attr.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("executing equals...");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Element other = (Element) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (attr == null) {
if (other.attr != null)
return false;
} else if (!attr.equals(other.attr))
return false;
return true;
}
private CatalogoActionTest getOuterType() {
return CatalogoActionTest.this;
}
public int compareTo(Element o) {
System.out.println("executing compareTo...");
//throw NPE when attr is null
return this.attr.compareTo(o.attr);//line 182
}
}
我想了解,如果compareTo需要为null安全,或者问题是构造一个新的对象与无效的数据。
这是堆栈跟踪:
java.lang.NullPointerException
at com.MyTest$Element.compareTo(MyTest.java:182)
at com.MyTest$Element.compareTo(MyTest.java:138)
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
嗯。 滑稽。 如果你检查TreeMap
第531行,你会发现它将key和thist比较:
compare(key, key);
所以基本上它调用
cv.compareTo(cv);
它会因为cv
中的attr
为空而崩溃。 类Element
没有正确实现compareTo
。 我想如果你将对象与抛出NPE的对象本身进行比较,它必须返回0。
在Java 7中TreeSet / TreeMap行为发生了变化。请考虑以下主要方法:
import java.util.TreeSet;
public class C {
public static void main(String[] args) {
TreeSet<Object> ts = new TreeSet<Object>();
ts.add(null);
System.out.println("TreeSet size is: " + ts.size());
}
}
在Java 6上运行良好:
$ java -showversion -cp . C
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
TreeSet size is: 1
Java 7的发展:
$ java -showversion -cp . C
java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode)
Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
at C.main(C.java:7)
链接地址: http://www.djcxy.com/p/76219.html
上一篇: compareTo triggered at first add call on TreeSet in Java 1.7