I have several Comparator - one for Date s, one for decimal places, one for percent, etc.
At first, my decimal comparator looked like this:
class NumericComparator implements Comparator<String> { @Override public int compare(String s1, String s2) { final Double i1 = Double.parseDouble(s1); final Double i2 = Double.parseDouble(s2); return i1.compareTo(i2); } }
Life was simple. Of course, this does not apply to the case when strings are not processed. So I improved
compare() :
class NumericComparator implements Comparator<String> { @Override public int compare(String s1, String s2) { final Double i1; final Double i2; try { i1 = Double.parseDouble(s1); } catch (NumberFormatException e) { try { i2 = Double.parseDouble(s2); } catch (NumberFormatException e2) { return 0; } return -1; } try { i2 = Double.parseDouble(s2); } catch (NumberFormatException e) { return 1; } return i1.compareTo(i2); } }
Life was better. The tests have become harder. However, my code browser noted: "What about null s?"
Ok, now I have to repeat the above with a NullPointerException or add the method body with:
if (s1 == null) { if (s2 == null) { return 0; } else { return -1; } } else if (s2 == null) { return 1; }
This method is huge. Worst of all, I need to repeat this pattern with three other classes that compare different types of strings and can raise three other exceptions when parsing.
I am not a Java expert. Is there a cleaner, tidier solution than - sigh - copy and paste? Do I have to trade correctness because of the lack of complexity, if it is documented?
Update:. Some have suggested that this is not a Comparator job to handle null values. Since the sort results are displayed to users, I want zeros to be sorted sequentially.