Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparator from nested POJO

I want to sort a list of my POJO by a property that is also a POJO. The Comparator should move null values to the end of the list. The nulls are already at second POJO level.

Assume following POJOs:

public class Foo {
    private Bar bar;
    private boolean set;
    // getter and setter omitted
}

public class Bar {
    private String name1;
    private String name2;
    // getter and setter omitted
}

Now I have a List<Foo> which should be sorted by Bar#name1.

So far I have following code:

Collections.sort(fullList, Comparator.comparing(Foo::getBar::getName1,
        Comparator.nullsLast(Comparator.naturalOrder())));

This sadly doesn't work, as the :: operator can't be chained. So I updated Bar class to implement Comparator<Bar>

public class Bar implements Comparator<Bar> {
    private String name1;
    private String name2;
    // getter and setter omitted

    @Override
    public int compare(Bar o1, Bar o2) {
        return o1.getName1().compareTo(o2.getName1());
    }
}

and changed my sorting code to:

Collections.sort(fullList, Comparator.comparing(Foo::getBar,
        Comparator.nullsLast(Comparator.naturalOrder())));

But this gives me compilation errors:

The method comparing(Function, Comparator) in the type Comparator is not applicable for the arguments (Foo::getBar, Comparator>>)

as well as

The type Foo does not define getBar(T) that is applicable here

What am I doing wrong on my second part? How do I fix it?


EDIT:

I just realized that a crucial part is missing.

In the list, Foos are never null, but Bar might be null. In the case that Bar is null, the Foo should be moved to the end of the list.

like image 996
XtremeBaumer Avatar asked Jul 05 '26 09:07

XtremeBaumer


1 Answers

you could simply use the lambda with your first approach:

fooList.sort(Comparator.comparing(f -> f.getBar().getName1(),
            Comparator.nullsLast(Comparator.naturalOrder())))

While you are looking towards making Bar comparable, you should do:

@Getter
class Bar implements Comparable<Bar> {
    private String name1;
    private String name2;

    @Override
    public int compareTo(Bar o) {
        return name1.compareTo(o.getName1());
    }
} 

and follow it up with

fooList.sort(Comparator.comparing(Foo::getBar,
        Comparator.nullsLast(Comparator.naturalOrder())));
like image 182
Naman Avatar answered Jul 07 '26 01:07

Naman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!