How to simplify a null-safe compareTo() implementation?

前端 未结 17 2039
醉酒成梦
醉酒成梦 2020-11-28 18:03

I\'m implementing compareTo() method for a simple class such as this (to be able to use Collections.sort() and other goodies offered by the Java pl

相关标签:
17条回答
  • 2020-11-28 18:52

    You can simply use Apache Commons Lang:

    result = ObjectUtils.compare(firstComparable, secondComparable)
    
    0 讨论(0)
  • 2020-11-28 18:54

    One of the simple way of using NullSafe Comparator is to use Spring implementation of it, below is one of the simple example to refer :

    public int compare(Object o1, Object o2) {
            ValidationMessage m1 = (ValidationMessage) o1;
            ValidationMessage m2 = (ValidationMessage) o2;
            int c;
            if (m1.getTimestamp() == m2.getTimestamp()) {
                c = NullSafeComparator.NULLS_HIGH.compare(m1.getProperty(), m2.getProperty());
                if (c == 0) {
                    c = m1.getSeverity().compareTo(m2.getSeverity());
                    if (c == 0) {
                        c = m1.getMessage().compareTo(m2.getMessage());
                    }
                }
            }
            else {
                c = (m1.getTimestamp() > m2.getTimestamp()) ? -1 : 1;
            }
            return c;
        }
    
    0 讨论(0)
  • 2020-11-28 18:56

    Using Java 8:

    private static Comparator<String> nullSafeStringComparator = Comparator
            .nullsFirst(String::compareToIgnoreCase); 
    
    private static Comparator<Metadata> metadataComparator = Comparator
            .comparing(Metadata::getName, nullSafeStringComparator)
            .thenComparing(Metadata::getValue, nullSafeStringComparator);
    
    public int compareTo(Metadata that) {
        return metadataComparator.compare(this, that);
    }
    
    0 讨论(0)
  • 2020-11-28 18:56

    You could design your class to be immutable (Effective Java 2nd Ed. has a great section on this, Item 15: Minimize mutability) and make sure upon construction that no nulls are possible (and use the null object pattern if needed). Then you can skip all those checks and safely assume the values are not null.

    0 讨论(0)
  • 2020-11-28 18:56

    I was looking for something similar and this seemed a bit complicated so I did this. I think it's a little easier to understand. You can use it as a Comparator or as a one liner. For this question you would change to compareToIgnoreCase(). As is, nulls float up. You can flip the 1, -1 if you want them to sink.

    StringUtil.NULL_SAFE_COMPARATOR.compare(getName(), o.getName());
    

    .

    public class StringUtil {
        public static final Comparator<String> NULL_SAFE_COMPARATOR = new Comparator<String>() {
    
            @Override
            public int compare(final String s1, final String s2) {
                if (s1 == s2) {
                    //Nulls or exact equality
                    return 0;
                } else if (s1 == null) {
                    //s1 null and s2 not null, so s1 less
                    return -1;
                } else if (s2 == null) {
                    //s2 null and s1 not null, so s1 greater
                    return 1;
                } else {
                    return s1.compareTo(s2);
                }
            }
        }; 
    
        public static void main(String args[]) {
            final ArrayList<String> list = new ArrayList<String>(Arrays.asList(new String[]{"qad", "bad", "sad", null, "had"}));
            Collections.sort(list, NULL_SAFE_COMPARATOR);
    
            System.out.println(list);
        }
    }
    
    0 讨论(0)
提交回复
热议问题