Компаратор из вложенного POJO - PullRequest
4 голосов
/ 17 января 2020

Я хочу отсортировать список моих POJO по свойству, которое также является POJO. Компаратор должен переместить значения null в конец списка. null уже на втором уровне POJO.

Допустим, следующие POJO:

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
}

Теперь у меня есть List<Foo>, который должен быть отсортирован по Bar#name1.

Пока у меня есть следующий код:

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

К сожалению, это не работает, так как оператор :: не может быть связан. Поэтому я обновил класс Bar для реализации 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());
    }
}

и изменил мой код сортировки на:

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

Но это дает мне ошибки компиляции:

Метод сравнения (Function, Comparator) в типе Comparator не применим для аргументов (Foo :: getBar, Comparator >>)

, а также

Тип Foo не определяет getBar (T), который применим здесь

Что я делаю неправильно во второй части? Как это исправить?


РЕДАКТИРОВАТЬ:

Я только что понял, что важная часть отсутствует.

В список, Foo никогда не бывает null, но Bar может быть null. В случае, если Bar равно null, Foo следует переместить в конец списка.

Ответы [ 2 ]

3 голосов
/ 17 января 2020

Вы можете просто использовать лямбду при первом подходе:

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

Пока вы хотите сделать Bar сопоставимым, вы должны сделать:

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

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

и проследите за этим

fooList.sort(Comparator.comparing(Foo::getBar,
        Comparator.nullsLast(Comparator.naturalOrder())));
0 голосов
/ 17 января 2020

Для Comparator<T> подпись:

static <T,U extends Comparable<? super U>> Comparator<T>
  comparing(Function<? super T,? extends U> keyExtractor)

Таким образом, результат должен Foo::getBar должен реализовывать Comparable. Bar реализует Comparator, а не Comparable.

...