Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should int compareTo() return when the parameter string is null?

It is said that when input parameter is null, compareTo() should throw a NullPointerException. However, I am implementing a class which needs to compare fields with the type of String. These fields need not to be mandatory. I wonder in this case,

1) What should I return when the input is null? Should any not-null strings lexicographically bigger or smaller than null?

and

2) If this is considered bad practice, is there any supporting arguments? Should I force the user to use empty strings instead? If using empty string, won't that confuse the case in which the field is not applicable and the case in which the field is empty? And if exception must be thrown, then except from warning the user in the manual, what else could/shall I do?

EDIT: I might not express myself clearly here, but in the program I am implementing, the strings that could be null are all fields or a class, which should not be null. In other words, the objects comparedTo() uses could not be null, just their private fields could be. So in this case, I believe if I implement compareTo() properly, it would not violate the transitive requirement since classes with null fields would be considered the same always. Am I right or am I interpreting this wrong?

Thank you all for the answers!

like image 913
zw324 Avatar asked Jun 06 '11 23:06

zw324


People also ask

Does compareTo work with null?

The compare() method in StringUtils class is a null-safe version of the compareTo() method of String class and handles null values by considering a null value less than a non-null value. Two null values are considered equal.

What does compareTo return for strings?

The compareTo() method compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The method returns 0 if the string is equal to the other string.

What does a negative return value indicate when calling the compareTo method on a string?

If first string is an empty string, the method returns a negative. If second string is an empty string, the method returns a positive number that is the length of the first string.

What data type is returned from the compareTo () method?

compareTo() Return Values compareTo() in java returns an integer value. It returns a positive integer if string1 is lexicographically greater than string2, negative if string2 is greater than string1, and zero if both are equal.


2 Answers

From javadoc for Comparable

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.

like image 56
Bala R Avatar answered Nov 12 '22 23:11

Bala R


Yes, there is no problem allowing null for instance fields - just make sure its sorting order is defined. Most natural would be putting it either before or after all real strings, but you could do anything here, just do it consistently. (For example, you could sort null like "null".)

Here is an example implementation for a single member:

class Example implements Comparable<Example> {

   @Nullable
   private String member;

   // TODO: getter, setter, constructor, ...

   public int compareTo(Example that) {
      if(this.member == null)
         if(that.member == null)
            return 0; //equal
         else
            return -1; // null is before other strings
       else // this.member != null
         if(that.member == null)
            return 1;  // all other strings are after null
         else
            return this.member.compareTo(that.member);
   }
}

Please note that the specification of Comparable.compareTo() only has a constraint for o.compareTo(null) (which should behave just like - null.compareTo(o), i.e. throw a NullPointerException), but not about how null fields are handled (it doesn't mention fields at all, so a class could return whatever it wants, as long as the antisymmetry, reflexivity and transitivity is ensured).

like image 31
Paŭlo Ebermann Avatar answered Nov 13 '22 00:11

Paŭlo Ebermann