I have a TreeSet with elements, and according to:
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html#compareTo%28T%29
[ The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false. ]
Element class have a not null safe compareTo method
I have the following code working on Java 1.5, but not in Java 1.7
- Why I need to do a Null Safe compareTo? and why javadoc say that?
- Why compareTo method was triggered at first add call in Java 1.7 but no in 1.5?
@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
}
}
I want to understand if compareTo needs be null safe, or the problem is construct a new object with invalid data.
This is the stacktrace:
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)