В FullComparator не работает сортировка по нескольким полям (channelName, DateCreated (в обратном порядке) и Fingerprint). Сортирует только по первому. Что делаю не так?
public class FullComparator implements Comparator<Capability> {
@Override
public int compare(Capability o1, Capability o2) {
if (o1 != null && o2 != null) {
if (o1.getChannelName() != null && o2.getChannelName() != null && !o1.getChannelName().equals(o2.getChannelName()))
return o1.getChannelName().compareTo(o2.getChannelName());
if (o1.getFingerprint() != null && o2.getFingerprint() != null && !o1.getFingerprint().equals(o2.getFingerprint()))
return o1.getFingerprint().compareTo(o2.getFingerprint());
if (o1.getDateCreated() != null && o2.getDateCreated() != null && !o2.getDateCreated().equals(o1.getDateCreated()))
return o2.getDateCreated().compareTo(o1.getDateCreated());
}
if (o1 == null && o2 != null)
return 1;
if (o1 != null)
return -1;
return 0;
}
}
public class Capability implements Comparable<Capability> {
private long id;
private String channelName;
private String fingerprint;
private boolean isActive;
private Date dateCreated;
public Capability(long id, String channelName, String fingerprint, boolean isActive, Date dateCreated) {
this.id = id;
this.channelName = channelName;
this.fingerprint = fingerprint;
this.isActive = isActive;
this.dateCreated = dateCreated;
}
public long getId() {
return id;
}
public String getChannelName() {
return channelName;
}
public String getFingerprint() {
return fingerprint;
}
public boolean isActive() {
return isActive;
}
public Date getDateCreated() {
return dateCreated;
}
@Override
public String toString() {
return "Capability{" +
"id=" + id +
", channelName='" + channelName + '\'' +
", fingerprint='" + fingerprint + '\'' +
", isActive=" + isActive +
", dateCreated=" + dateCreated +
'}';
}
public class DemoComparator {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
Capability capability1 = new Capability(1001, "A", "R", true, sdf.parse("2015-12-15"));
Capability capability2 = new Capability(1005, "D", "Z", false, sdf.parse("2010-12-15"));
Capability capability3 = new Capability(900, null, "O", true, sdf.parse("2013-12-15"));
Capability capability4 = new Capability(900, "B", "L", false, sdf.parse("2008-12-15"));
ArrayList<Capability> capabilities = new ArrayList<>();
capabilities.add(capability1);
capabilities.add(capability2);
capabilities.add(null);
capabilities.add(capability4);
System.out.println(capabilities);
System.out.println();
capabilities.sort(new FullComparator());
System.out.println(capabilities);
}
}
И разве метод может отсортировать все поля? Тогда получается нужно объектам полями меняться, чтобы одновременно в конечном результате все поля были в нужном порядке.
Видимо вы не до конца понимаете смысл сортировки по нескольким полям. Проще всего рассмотреть на примере учеников.
Ученик имеет имя и фамилию, а также год рождения. Существует следующий набор учеников:
В данной ситуации сортировка по нескольким полям (Фамилия, Имя, Год рождения -> по возрастанию) предполагает, что сначала ученики будут отсортированы по полю фамилия, затем внутри групп отсортированных по фамилии произойдет сортировка по имени, затем внутри групп отсортированных по имени и фамилии произойдет сортировка по году рождения. Таким образом на выходе получим следующий список:
Если так случится, что в список добавится еще один Иванов Сергей, но 1999 года рождения, то список отсортируется следующим образом:
Ваш код рабочий и вполне справляется с поставленной задачей, чтобы в этом убедиться, достаточно добавить еще один объект Capability в ваш список:
Capability capability5 = new Capability(900, "D", "L", false, sdf.parse("2008-12-15"));
capabilities.add(capability5);
Данный объект после сортировки будет находиться после объекта с channelName A, но перед объектом с fingerPrint Z
И кстати, если используется java8, то вполне можно обойтись и без класса FullComparator:
Comparator<Capability> comp = Comparator.nullsLast(Comparator.comparing(Capability::getChannelName).thenComparing(Capability::getFingerprint).thenComparing(Capability::getDateCreated, Comparator.reverseOrder()));
capabilities.sort(comp);
Таким образом мы буквально пишем: Отсортируй список так, чтобы null элементы
оказались в конце, и сортируй сначала по channelName, потом по
Fingerprint, потом по DateCreate в обратном порядке.
Но будьте внимательны, если захотите добавить в лист capability3, который имеет вторым аргументом в конструкторе null (я так понимаю, это channelName), то нужно будет написать что-то вроде:
Comparator<Capability> comp = Comparator.nullsLast(Comparator.comparing(Capability::getChannelName, Comparator.nullsFirst(Comparator.naturalOrder())).thenComparing(Capability::getFingerprint).thenComparing(Capability::getDateCreated, Comparator.reverseOrder()));
capabilities.sort(comp);
То есть все то же самое, но дополнительно написать, чтобы null значения в channelName при сортировке этого поля стояли в начале.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости