195

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 platform):

public class Metadata implements Comparable<Metadata> {
    private String name;
    private String value;

// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}

I want the natural ordering for these objects to be: 1) sorted by name and 2) sorted by value if name is the same; both comparisons should be case-insensitive. For both fields null values are perfectly acceptable, so compareTo must not break in these cases.

The solution that springs to mind is along the lines of the following (I'm using "guard clauses" here while others might prefer a single return point, but that's beside the point):

// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
    if (this.name == null && other.name != null){
        return -1;
    }
    else if (this.name != null && other.name == null){
        return 1;
    }
    else if (this.name != null && other.name != null) {
        int result = this.name.compareToIgnoreCase(other.name);
        if (result != 0){
            return result;
        }
    }

    if (this.value == null) {
        return other.value == null ? 0 : -1;
    }
    if (other.value == null){
        return 1;
    }

    return this.value.compareToIgnoreCase(other.value);
}

This does the job, but I'm not perfectly happy with this code. Admittedly it isn't very complex, but is quite verbose and tedious.

The question is, how would you make this less verbose (while retaining the functionality)? Feel free to refer to Java standard libraries or Apache Commons if they help. Would the only option to make this (a little) simpler be to implement my own "NullSafeStringComparator", and apply it for comparing both fields?

Edits 1-3: Eddie's right; fixed the "both names are null" case above

About the accepted answer

I asked this question back in 2009, on Java 1.6 of course, and at the time the pure JDK solution by Eddie was my preferred accepted answer. I never got round to changing that until now (2017).

There are also 3rd party library solutions—a 2009 Apache Commons Collections one and a 2013 Guava one, both posted by me—that I did prefer at some point in time.

I now made the clean Java 8 solution by Lukasz Wiktor the accepted answer. That should definitely be preferred if on Java 8, and these days Java 8 should be available to nearly all projects.

Community
  • 1
  • 1
Jonik
  • 80,077
  • 70
  • 264
  • 372

18 Answers18

242

You can simply use Apache Commons Lang:

result = ObjectUtils.compare(firstComparable, secondComparable)
bluish
  • 26,356
  • 27
  • 122
  • 180
Dag
  • 10,079
  • 8
  • 51
  • 74
  • 6
    (@Kong: This takes care of null-safety but not case-insensitivity which was another aspect of the original question. Thus not changing the accepted answer.) – Jonik Jul 27 '13 at 00:12
  • 3
    Also, in my mind *Apache Commons* should not be the accepted answer in 2013. (Even if some subprojects are better maintained than others.) [Guava can be used to achieve the same thing](http://stackoverflow.com/a/500643/56285); see `nullsFirst()` / `nullsLast()`. – Jonik Dec 18 '13 at 22:45
  • 10
    @Jonik Why do you think that Apache Commons should not be the accepted answer in 2013? – reallynice Aug 07 '15 at 08:30
  • 3
    Big parts of Apache Commons are legacy / poorly maintained / low-quality stuff. There are better alternatives for most things it provides, for example in [Guava](https://github.com/google/guava) which is a very high quality lib throughout, and increasingly in JDK itself. Around 2005 yes, Apache Commons was the shit, but these days there is no need for it in most projects. (Sure, there are exceptions; for example if I needed an FTP client for some reason, I'd probably use the one in Apache Commons Net, and so on.) – Jonik Jul 12 '16 at 19:42
  • 8
    @Jonik, how would you answer the question using Guava? Your assertion that Apache Commons Lang (package `org.apache.commons.lang3`) is "legacy/poorly maintained/low-quality" is false or at best baseless. Commons Lang3 is easy to understand and use, and it's actively maintained. It's probably my most oft-used library (apart from Spring Framework and Spring Security) - the [StringUtils](https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html) class with its null-safe methods makes input normalization trivial, for example. – Paul Mar 31 '17 at 19:54
  • What I wrote was "Big parts of *Apache Commons* are legacy" and I think that remains true. You may be right that *Commons Lang 3* is fine and actively maintained. In every case, nowadays the **[Java 8 solution](http://stackoverflow.com/a/23908426/56285) is the way to go**. Back in 2013 I did post a [Guava version](http://stackoverflow.com/a/500643/56285) but for this particular problem I'd no longer use Guava (unless Java 8 could not be used for whatever reason). – Jonik Apr 06 '17 at 10:07
  • 2
    Including a gigantic kitchen sink library to save a few lines of code? Win. – Jeffrey Blattman Apr 11 '17 at 19:37
  • In streams it would look like this:`.sorted((o1, o2) -> ObjectUtils.compare(o1.getAttribute(), o2.getAttribute()))`. – Michał Stochmal Oct 19 '18 at 08:45
  • I don't understand why this answer has 195 votes, because this answer yields a a StackOverflow Exception, because the ObjectUtils compare method simply checks for null, but for the real comparison of the fields it calls the compareTo method of the Comparable instance, i.e. it cannot be used inside this method or it will loop... Or did this change in time and cannot be done now anymore? – jan Oct 02 '19 at 09:09
  • If you're going to use Apache Commons Lang3 then use `CompareToBuilder`, not `ObjectUtils`. – Paul Jul 30 '22 at 15:43
222

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);
}
xehpuk
  • 7,814
  • 3
  • 30
  • 54
Lukasz Wiktor
  • 19,644
  • 5
  • 69
  • 82
  • 12
    I support using Java 8 built-in stuff in favor of Apache Commons Lang, but that Java 8 code is quite ugly, and still verbose. I will stick with org.apache.commons.lang3.builder.CompareToBuilder for the moment. – jschreiner May 12 '17 at 07:57
  • 2
    This does not work for Collections.sort(Arrays.asList(null, val1, null, val2, null)) as it will try to call compareTo() on a null object. It looks like a problem with the collections framework to be honest, trying to figure out how to corner this. – Pedro Borges Jun 12 '18 at 11:52
  • 3
    @PedroBorges The author asked about sorting container objects that possess sortable fields (where those fields may be null), not about sorting null container references. So, while your comment is correct, in that `Collections.sort(List)` does not work when the List contains nulls, the comment is not relevant to the question. – Scrubbie Jan 27 '20 at 17:21
  • 2
    @PedroBorges `null` values can not have a natural order. If you want to sort a list or array containing `null`, you must use a `Comparator`. – Holger Apr 09 '21 at 14:57
96

I would implement a null safe comparator. There may be an implementation out there, but this is so straightforward to implement that I've always rolled my own.

Note: Your comparator above, if both names are null, won't even compare the value fields. I don't think this is what you want.

I would implement this with something like the following:

// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(final Metadata other) {

    if (other == null) {
        throw new NullPointerException();
    }

    int result = nullSafeStringComparator(this.name, other.name);
    if (result != 0) {
        return result;
    }

    return nullSafeStringComparator(this.value, other.value);
}

public static int nullSafeStringComparator(final String one, final String two) {
    if (one == null ^ two == null) {
        return (one == null) ? -1 : 1;
    }

    if (one == null && two == null) {
        return 0;
    }

    return one.compareToIgnoreCase(two);
}

EDIT: Fixed typos in code sample. That's what I get for not testing it first!

EDIT: Promoted nullSafeStringComparator to static.

Sentinel
  • 6,379
  • 1
  • 18
  • 23
Eddie
  • 53,828
  • 22
  • 125
  • 145
  • Your code is a little bit botched: final is not necessary here, the first character of the String class is capitalized in Java. Furthermore, return 1:-1 is not valid Java. I'd suggest a nested if (one == null) {if two == null) return 0; else return -1;}else{if (two == null) return 0; else return 1;} – phihag Jan 26 '09 at 23:43
  • Yup. I should have tested it first. Now it's tested. :) – Eddie Jan 26 '09 at 23:52
  • 2
    Regarding nested "if" ... I find the nested if to be less readable for this case, so I avoid it. Yes, sometimes there will be an unnecessary comparison due to this. final for parameters is not necessary, but is a good idea. – Eddie Jan 26 '09 at 23:58
  • Or return one==null ? (two==null ? 0 :-1) : two==null ? -1 : one.compareToIgnoreCase(two); – Peter Lawrey Feb 01 '09 at 13:53
  • @Peter Lawrey: Yes, but that is less readable. And with a good optimizer, there should be no real speed difference between the optimized and the readable version. – Eddie Feb 01 '09 at 16:23
  • 9
    @phihag - I know it's over 3 years, BUT... the `final` keyword is not truly necessary (Java code is already verbose as it is.) However, it does prevent reuse of parameters as local vars (a terrible coding practice.) As our collective understanding of software gets better over time, we know that things should be final/const/inmutable by default. So I prefer a bit extra verbosity in using `final` in parameter declarations (however trivial the function may be) to get `inmutability-by-quasi-default`.) The comprehensibility/maintainability overhead of it is negligible in the grand scheme of things. – luis.espinal Jul 13 '12 at 14:04
  • 26
    @James McMahon I have to disagree. Xor (^) could simply be replaced with not-equal (!=). It even compiles to the same byte code. The usage of != vs ^ is just a matter of taste and readability. So, judging by the fact that you were surprised I would say that it does not belong here. Use xor when you are trying to calculate a checksum. In most other cases (like this one) let's stick to !=. – bvdb Jul 27 '14 at 11:32
  • 2
    @bvdb: if the `one==null && two==null` test is done first, than the other case can be made much more readable with `one==null || two==null`. For that matter, I suggest: `if (one==null || two==null) { if (one==two) return 0; return lhs==null ? -1 : 1; }` – Harvey Nov 23 '15 at 18:07
  • In the second if you can just write if (one == null) (two will also be null because of the preceeding xor) – Paul Praet May 26 '16 at 10:10
  • 5
    It is easy to extend this answer by replacing String with T, T declared as >... and then we can safely compare any nullable Comparable objects – Thierry Jul 05 '16 at 08:24
23

See the bottom of this answer for updated (2013) solution using Guava.


This is what I ultimately went with. It turned out we already had a utility method for null-safe String comparison, so the simplest solution was to make use of that. (It's a big codebase; easy to miss this kind of thing :)

public int compareTo(Metadata other) {
    int result = StringUtils.compare(this.getName(), other.getName(), true);
    if (result != 0) {
        return result;
    }
    return StringUtils.compare(this.getValue(), other.getValue(), true);
}

This is how the helper is defined (it's overloaded so that you can also define whether nulls come first or last, if you want):

public static int compare(String s1, String s2, boolean ignoreCase) { ... }

So this is essentially the same as Eddie's answer (although I wouldn't call a static helper method a comparator) and that of uzhin too.

Anyway, in general, I would have strongly favoured Patrick's solution, as I think it's a good practice to use established libraries whenever possible. (Know and use the libraries as Josh Bloch says.) But in this case that would not have yielded the cleanest, simplest code.

Edit (2009): Apache Commons Collections version

Actually, here's a way to make the solution based on Apache Commons NullComparator simpler. Combine it with the case-insensitive Comparator provided in String class:

public static final Comparator<String> NULL_SAFE_COMPARATOR 
    = new NullComparator(String.CASE_INSENSITIVE_ORDER);

@Override
public int compareTo(Metadata other) {
    int result = NULL_SAFE_COMPARATOR.compare(this.name, other.name);
    if (result != 0) {
        return result;
    }
    return NULL_SAFE_COMPARATOR.compare(this.value, other.value);
}

Now this is pretty elegant, I think. (Just one small issue remains: the Commons NullComparator doesn't support generics, so there's an unchecked assignment.)

Update (2013): Guava version

Nearly 5 years later, here's how I'd tackle my original question. If coding in Java, I would (of course) be using Guava. (And quite certainly not Apache Commons.)

Put this constant somewhere, e.g. in "StringUtils" class:

public static final Ordering<String> CASE_INSENSITIVE_NULL_SAFE_ORDER =
    Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsLast(); // or nullsFirst()

Then, in public class Metadata implements Comparable<Metadata>:

@Override
public int compareTo(Metadata other) {
    int result = CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.name, other.name);
    if (result != 0) {
        return result;
    }
    return CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.value, other.value);
}    

Of course, this is nearly identical to the Apache Commons version (both use JDK's CASE_INSENSITIVE_ORDER), the use of nullsLast() being the only Guava-specific thing. This version is preferable simply because Guava is preferable, as a dependency, to Commons Collections. (As everyone agrees.)

If you were wondering about Ordering, note that it implements Comparator. It's pretty handy especially for more complex sorting needs, allowing you for example to chain several Orderings using compound(). Read Ordering Explained for more!

Community
  • 1
  • 1
Jonik
  • 80,077
  • 70
  • 264
  • 372
  • 2
    String.CASE_INSENSITIVE_ORDER really does make the solution much cleaner. Nice update. – Patrick Feb 02 '09 at 19:19
  • 2
    If you use Apache Commons anyway, there's a [`ComparatorChain`](https://commons.apache.org/collections/apidocs/org/apache/commons/collections/comparators/ComparatorChain.html) so you don't need an own `compareTo` method. – amoebe Sep 23 '12 at 19:23
14

I always recommend using Apache commons since it will most likely be better than one you can write on your own. Plus you can then do 'real' work rather then reinventing.

The class you are interested in is the Null Comparator. It allows you to make nulls high or low. You also give it your own comparator to use when the two values are not null.

In your case you can have a static member variable that does the comparison and then your compareTo method just references that.

Somthing like

class Metadata implements Comparable<Metadata> {
private String name;
private String value;

static NullComparator nullAndCaseInsensitveComparator = new NullComparator(
        new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                // inputs can't be null
                return o1.compareToIgnoreCase(o2);
            }

        });

@Override
public int compareTo(Metadata other) {
    if (other == null) {
        return 1;
    }
    int res = nullAndCaseInsensitveComparator.compare(name, other.name);
    if (res != 0)
        return res;

    return nullAndCaseInsensitveComparator.compare(value, other.value);
}

}

Even if you decide to roll your own, keep this class in mind since it is very useful when ordering lists thatcontain null elements.

Patrick
  • 3,901
  • 1
  • 25
  • 30
  • Thanks, I was sort of hoping there would be something like this in Commons! In this case, however, I didn't end up using it: http://stackoverflow.com/questions/481813/how-to-simplify-a-null-safe-compareto-implementation/500643#500643 – Jonik Feb 01 '09 at 11:40
  • Just realised your approach can be simplified by using String.CASE_INSENSITIVE_ORDER; see my edited follow-up answer. – Jonik Feb 01 '09 at 16:18
  • This is good but the "if (other == null) {" check should not be there. The Javadoc for Comparable says that compareTo should throw a NullPointerException if other is null. – Daniel Alexiuc Dec 13 '12 at 02:36
7

I know that it may be not directly answer to your question, because you said that null values have to be supported.

But I just want to note that supporting nulls in compareTo is not in line with compareTo contract described in official javadocs 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.

So I would either throw NullPointerException explicitly or just let it be thrown first time when null argument is being dereferenced.

Umpa
  • 334
  • 11
  • 16
Piotr Sobczyk
  • 6,443
  • 7
  • 47
  • 70
6

You can extract method:

public int cmp(String txt, String otherTxt)
{
    if ( txt == null )
        return otherTxt == null ? 0 : 1;
     
    if ( otherTxt == null )
          return 1;

    return txt.compareToIgnoreCase(otherTxt);
}

public int compareTo(Metadata other) {
   int result = cmp( name, other.name); 
   if ( result != 0 )  return result;
   return cmp( value, other.value); 

}

JGFMK
  • 8,425
  • 4
  • 58
  • 92
Yoni Roit
  • 28,280
  • 7
  • 36
  • 32
4
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Comparator;

public class TestClass {

    public static void main(String[] args) {

        Student s1 = new Student("1","Nikhil");
        Student s2 = new Student("1","*");
        Student s3 = new Student("1",null);
        Student s11 = new Student("2","Nikhil");
        Student s12 = new Student("2","*");
        Student s13 = new Student("2",null);
        List<Student> list = new ArrayList<Student>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s11);
        list.add(s12);
        list.add(s13);

        list.sort(Comparator.comparing(Student::getName,Comparator.nullsLast(Comparator.naturalOrder())));

        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Student student = (Student) iterator.next();
            System.out.println(student);
        }


    }

}

output is

Student [name=*, id=1]
Student [name=*, id=2]
Student [name=Nikhil, id=1]
Student [name=Nikhil, id=2]
Student [name=null, id=1]
Student [name=null, id=2]
Nikhil Kumar K
  • 1,089
  • 10
  • 13
4

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.

Fabian Steeg
  • 44,988
  • 7
  • 85
  • 112
  • Yes, that's generally a good solution, and simplifies many things - but here I was more interested in the case where null values are allowed, for one reason or another, and must be taken into account :) – Jonik Jan 26 '09 at 23:57
2

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);
    }
}
Dustin
  • 2,064
  • 1
  • 16
  • 12
2

In case anyone using Spring, there is a class org.springframework.util.comparator.NullSafeComparator that does this for you as well. Just decorate your own comparable with it like this

new NullSafeComparator<YourObject>(new YourComparable(), true)

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/comparator/NullSafeComparator.html

2

we can use java 8 to do a null-friendly comparasion between object. supposed i hava a Boy class with 2 fields: String name and Integer age and i want to first compare names and then ages if both are equal.

static void test2() {
    List<Boy> list = new ArrayList<>();
    list.add(new Boy("Peter", null));
    list.add(new Boy("Tom", 24));
    list.add(new Boy("Peter", 20));
    list.add(new Boy("Peter", 23));
    list.add(new Boy("Peter", 18));
    list.add(new Boy(null, 19));
    list.add(new Boy(null, 12));
    list.add(new Boy(null, 24));
    list.add(new Boy("Peter", null));
    list.add(new Boy(null, 21));
    list.add(new Boy("John", 30));

    List<Boy> list2 = list.stream()
            .sorted(comparing(Boy::getName, 
                        nullsLast(naturalOrder()))
                   .thenComparing(Boy::getAge, 
                        nullsLast(naturalOrder())))
            .collect(toList());
    list2.stream().forEach(System.out::println);

}

private static class Boy {
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Boy(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "name: " + name + " age: " + age;
    }
}

and the result:

    name: John age: 30
    name: Peter age: 18
    name: Peter age: 20
    name: Peter age: 23
    name: Peter age: null
    name: Peter age: null
    name: Tom age: 24
    name: null age: 12
    name: null age: 19
    name: null age: 21
    name: null age: 24
Leo Ng
  • 21
  • 1
1

For the specific case where you know the data will not have nulls (always a good idea for strings) and the data is really large, you are still doing three comparisons before actually comparing the values, if you know for sure this is your case, you can optimize a tad bit. YMMV as readable code trumps minor optimization:

        if(o1.name != null && o2.name != null){
            return o1.name.compareToIgnoreCase(o2.name);
        }
        // at least one is null
        return (o1.name == o2.name) ? 0 : (o1.name != null ? 1 : -1);
kisna
  • 2,869
  • 1
  • 25
  • 30
1

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;
    }
Amandeep Singh
  • 3,754
  • 8
  • 51
  • 72
0

Another Apache ObjectUtils example. Able to sort other types of objects.

@Override
public int compare(Object o1, Object o2) {
    String s1 = ObjectUtils.toString(o1);
    String s2 = ObjectUtils.toString(o2);
    return s1.toLowerCase().compareTo(s2.toLowerCase());
}
snp0k
  • 398
  • 1
  • 5
  • 12
0

This is my implementation that I use to sort my ArrayList. the null classes are sorted to the last.

for my case, EntityPhone extends EntityAbstract and my container is List < EntityAbstract>.

the "compareIfNull()" method is used for null safe sorting. The other methods are for completeness, showing how compareIfNull can be used.

@Nullable
private static Integer compareIfNull(EntityPhone ep1, EntityPhone ep2) {

    if (ep1 == null || ep2 == null) {
        if (ep1 == ep2) {
            return 0;
        }
        return ep1 == null ? -1 : 1;
    }
    return null;
}

private static final Comparator<EntityAbstract> AbsComparatorByName = = new Comparator<EntityAbstract>() {
    @Override
    public int compare(EntityAbstract ea1, EntityAbstract ea2) {

    //sort type Phone first.
    EntityPhone ep1 = getEntityPhone(ea1);
    EntityPhone ep2 = getEntityPhone(ea2);

    //null compare
    Integer x = compareIfNull(ep1, ep2);
    if (x != null) return x;

    String name1 = ep1.getName().toUpperCase();
    String name2 = ep2.getName().toUpperCase();

    return name1.compareTo(name2);
}
}


private static EntityPhone getEntityPhone(EntityAbstract ea) { 
    return (ea != null && ea.getClass() == EntityPhone.class) ?
            (EntityPhone) ea : null;
}
Angel Koh
  • 12,479
  • 7
  • 64
  • 91
0

A generic utility class which can handle the null aspect and be used in a custom compareTo method implementation may look like this:

/**
 * Generic utility class for null-safe comparison.
 */
public class Comparing
{
    /**
     * Compares two objects for order. Returns a negative integer, zero, or a
     * positive integer if the first object is less than, equal to, or greater
     * than the second object. Any of the objects can be null. A null value is
     * considered to be less than a non-null value.
     * 
     * @param <T>
     * @param a the first object.
     * @param b the second object.
     * @return an integer value.
     */
    public static <T extends Comparable<T>> int compareTo( T a, T b )
    {
        if ( a == b )
        {
            return 0;
        }

        return a != null ? b != null ? a.compareTo( b ) : 1 : -1;
    }
}
lars
  • 640
  • 4
  • 10
-1

If you want a simple Hack:

arrlist.sort((o1, o2) -> {
    if (o1.getName() == null) o1.setName("");
    if (o2.getName() == null) o2.setName("");

    return o1.getName().compareTo(o2.getName());
})

if you want put nulls to end of the list just change this in above metod

return o2.getName().compareTo(o1.getName());
MarsPeople
  • 1,772
  • 18
  • 30