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

18

198

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.

Mastectomy answered 26/1, 2009 at 23:25 Comment(1)
#369883Rabin
M
228

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);
}
Mernamero answered 28/5, 2014 at 9:57 Comment(4)
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.Dulcle
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.Anaxagoras
@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.Jacquelinjacqueline
@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.Perdu
F
246

You can simply use Apache Commons Lang:

result = ObjectUtils.compare(firstComparable, secondComparable)
Factor answered 5/4, 2012 at 9:29 Comment(10)
(@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.)Mastectomy
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; see nullsFirst() / nullsLast().Mastectomy
@Mastectomy Why do you think that Apache Commons should not be the accepted answer in 2013?Alcoholize
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 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.)Mastectomy
@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 class with its null-safe methods makes input normalization trivial, for example.Inquisitionist
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 is the way to go. Back in 2013 I did post a Guava version but for this particular problem I'd no longer use Guava (unless Java 8 could not be used for whatever reason).Mastectomy
Including a gigantic kitchen sink library to save a few lines of code? Win.Disenthral
In streams it would look like this:.sorted((o1, o2) -> ObjectUtils.compare(o1.getAttribute(), o2.getAttribute())).Walliw
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?Seroka
If you're going to use Apache Commons Lang3 then use CompareToBuilder, not ObjectUtils.Inquisitionist
M
228

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);
}
Mernamero answered 28/5, 2014 at 9:57 Comment(4)
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.Dulcle
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.Anaxagoras
@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.Jacquelinjacqueline
@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.Perdu
C
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.

Carousel answered 26/1, 2009 at 23:35 Comment(10)
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;}Gymnastic
Yup. I should have tested it first. Now it's tested. :)Carousel
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.Carousel
Or return one==null ? (two==null ? 0 :-1) : two==null ? -1 : one.compareToIgnoreCase(two);Rhodian
@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.Carousel
@Gymnastic - 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.Jacklyn
@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 !=.Clarettaclarette
@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; }Orangewood
In the second if you can just write if (one == null) (two will also be null because of the preceeding xor)Barcellona
It is easy to extend this answer by replacing String with T, T declared as <T extends Comparable<T>>... and then we can safely compare any nullable Comparable objectsSoniasonic
M
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!

Mastectomy answered 1/2, 2009 at 11:35 Comment(2)
String.CASE_INSENSITIVE_ORDER really does make the solution much cleaner. Nice update.Unsupportable
If you use Apache Commons anyway, there's a ComparatorChain so you don't need an own compareTo method.Smithsonite
U
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.

Unsupportable answered 27/1, 2009 at 0:4 Comment(3)
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: #482313Mastectomy
Just realised your approach can be simplified by using String.CASE_INSENSITIVE_ORDER; see my edited follow-up answer.Mastectomy
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.Whaley
B
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.

Bullroarer answered 24/7, 2013 at 6:19 Comment(0)
U
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); 

}

Undergrowth answered 26/1, 2009 at 23:38 Comment(1)
Should the "0 : 1" not be "0 : -1" ?Mauchi
P
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.

Pickwickian answered 26/1, 2009 at 23:30 Comment(1)
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 :)Mastectomy
T
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]
Torey answered 13/2, 2017 at 16:48 Comment(0)
M
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);
    }
}
Mendel answered 7/10, 2014 at 16:38 Comment(0)
Y
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

Yoohoo answered 19/1, 2016 at 12:33 Comment(0)
E
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
Eocene answered 18/3, 2016 at 18:24 Comment(0)
R
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);
Redskin answered 12/7, 2016 at 2:40 Comment(0)
M
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;
    }
Marquita answered 8/3, 2019 at 19:0 Comment(0)
B
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());
}
Battledore answered 11/8, 2015 at 15:39 Comment(0)
K
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;
}
Kristelkristen answered 15/3, 2016 at 18:43 Comment(0)
P
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;
    }
}
Prostomium answered 18/11, 2022 at 17:18 Comment(0)
G
-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());
Grisons answered 21/3, 2020 at 13:31 Comment(1)
Modifying the objects while comparing them is a pretty bad hack imo. You never know what the rest of the system does with those valuesTutelary

© 2022 - 2024 — McMap. All rights reserved.