сортировать список на основе ссылок [duplicate]

У меня есть простой класс

public class ActiveAlarm {
    public long timeStarted;
    public long timeEnded;
    private String name = "";
    private String description = "";
    private String event;
    private boolean live = false;
}

и List<ActiveAlarm> con. Как отсортировать в порядке возрастания по timeStarted, затем по timeEnded? Может ли кто-нибудь помочь? Я знаю в C ++ с общим алгоритмом и оператором перегрузки & lt ;, но я новичок в Java.

112
задан 19 October 2015 в 19:03

11 ответов

Как уже упоминалось, вы можете сортировать по:

Выполнять реализацию объекта Comparable Или передать Comparator в Collections.sort

Если вы оба делаете Comparable будут игнорироваться, а Comparator будет использоваться. Это помогает объектам с ценными объектами иметь свой собственный логический Comparable, который является наиболее разумным для вашего объекта значения, в то время как каждый индивидуальный вариант использования имеет свою собственную реализацию.

0
ответ дан 15 August 2018 в 16:43
public class ActiveAlarm implements Comparable<ActiveAlarm> {
    public long timeStarted;
    public long timeEnded;
    private String name = "";
    private String description = "";
    private String event;
    private boolean live = false;

    public int compareTo(ActiveAlarm a) {
        if ( this.timeStarted > a.timeStarted )
            return 1;
        else if ( this.timeStarted < a.timeStarted )
            return -1;
        else {
             if ( this.timeEnded > a.timeEnded )
                 return 1;
             else
                 return -1;
        }
 }

Это должно дать вам приблизительную идею. Как только это будет сделано, вы можете вызвать Collections.sort() в списке.

4
ответ дан 15 August 2018 в 16:43

Мы можем отсортировать список одним из двух способов:

Мы можем отсортировать список одним из двух способов: : при необходимости использовать логику сортировки в нескольких местах Если вы хотите использовать логику сортировки в одном месте, вы можете написать анонимный внутренний класс следующим образом или извлечь из компаратора и использовать его в нескольких местах

  Collections.sort(arrayList, new Comparator<ActiveAlarm>() {
        public int compare(ActiveAlarm o1, ActiveAlarm o2) {
            //Sorts by 'TimeStarted' property
            return o1.getTimeStarted()<o2.getTimeStarted()?-1:o1.getTimeStarted()>o2.getTimeStarted()?1:doSecodaryOrderSort(o1,o2);
        }

        //If 'TimeStarted' property is equal sorts by 'TimeEnded' property
        public int doSecodaryOrderSort(ActiveAlarm o1,ActiveAlarm o2) {
            return o1.getTimeEnded()<o2.getTimeEnded()?-1:o1.getTimeEnded()>o2.getTimeEnded()?1:0;
        }
    });

Мы можем иметь нулевую проверку для свойств, если бы мы могли использовать «Длинный» вместо «длинный».

2. Использование Comparable (естественный порядок): если алгоритм сортировки всегда придерживается одного свойства: напишите класс, который реализует «Comparable» и переопределяет метод «compareTo», как определено ниже

class ActiveAlarm implements Comparable<ActiveAlarm>{

public long timeStarted;
public long timeEnded;
private String name = "";
private String description = "";
private String event;
private boolean live = false;

public ActiveAlarm(long timeStarted,long timeEnded) {
    this.timeStarted=timeStarted;
    this.timeEnded=timeEnded;
}

public long getTimeStarted() {
    return timeStarted;
}

public long getTimeEnded() {
    return timeEnded;
}

public int compareTo(ActiveAlarm o) {
    return timeStarted<o.getTimeStarted()?-1:timeStarted>o.getTimeStarted()?1:doSecodaryOrderSort(o);
}

public int doSecodaryOrderSort(ActiveAlarm o) {
    return timeEnded<o.getTimeEnded()?-1:timeEnded>o.getTimeEnded()?1:0;
}

}

метод сортировки вызовов для сортировки на основе естественного упорядочения

Collections.sort(list);
19
ответ дан 15 August 2018 в 16:43

Сравнение GuavaChain:

Collections.sort(list, new Comparator<ActiveAlarm>(){
            @Override
            public int compare(ActiveAlarm a1, ActiveAlarm a2) {
                 return ComparisonChain.start()
                       .compare(a1.timestarted, a2.timestarted)
                       //...
                       .compare(a1.timeEnded, a1.timeEnded).result();
            }});
31
ответ дан 15 August 2018 в 16:43
  • 1
    Вы можете оценить новый Java 8 API Comparator.comparing().thenComparing() ... – Lukas Eder 13 March 2016 в 18:45
  • 2
    Следите за возвращением. В случае переполнения вы можете получить неправильный результат. – krzychu 9 June 2018 в 21:19

В java8 + это можно записать в одну строку следующим образом:

collectionObjec.sort (comparator_lamda) или comparator.comparing (CollectionType :: getterOfProperty)

код:

ListOfActiveAlarmObj.sort((a,b->a.getTimeStarted().compareTo(b.getTimeStarted())))

или

ListOfActiveAlarmObj.sort(Comparator.comparing(ActiveAlarm::getTimeStarted))
2
ответ дан 15 August 2018 в 16:43

Вы можете вызвать Collections.sort () и передать в Comparator, который вам нужно написать, чтобы сравнить различные свойства объекта.

0
ответ дан 15 August 2018 в 16:43

Использование Comparator

Пример:

class Score {

    private String name;
    private List<Integer> scores;
    // +accessor methods
}
    Collections.sort(scores, new Comparator<Score>() {

        public int compare(Score o1, Score o2) {
            // compare two instance of `Score` and return `int` as result.
            return o2.getScores().get(0).compareTo(o1.getScores().get(0));
        }
    });

С Java 8 и далее вы можете просто использовать лямбда-выражение для представления Экземпляр компаратора.

Collections.sort(scores, (s1, s2) -> { /* compute and return int */ });
101
ответ дан 15 August 2018 в 16:43
  • 1
    Я запутался в том, где вы поместили второй бит кода ... – Micro 12 January 2016 в 05:52
  • 2
    Что делает compareTo()? От куда это? Где я должен это определить? – Asqiir 24 July 2017 в 15:58
  • 3
    @Asqiir getScores() является получателем для scores, который является List<Integer>. Когда вы выполняете getScores().get(0), вы получаете объект Integer. Integer уже реализован метод compareTo(anotherInteger), вам не нужно его определять. – Luis G. 9 August 2018 в 13:54

Вы можете использовать Collections.sort и передать свой собственный Comparator<ActiveAlarm>

0
ответ дан 15 August 2018 в 16:43

С помощью Java8 это можно сделать еще более чистым, используя комбинацию Comparator и Lambda expressions

Пример:

class Student{

    private String name;
    private List<Score> scores;

    // +accessor methods
}

class Score {

    private int grade;
    // +accessor methods
}
    Collections.sort(student.getScores(), Comparator.comparing(Score::getGrade);
2
ответ дан 15 August 2018 в 16:43

В java вам нужно использовать статический метод Collections.sort. Ниже приведен пример списка объектов CompanyRole, отсортированных сначала, а затем и до конца. Вы можете легко адаптироваться к своему собственному объекту.

private static void order(List<TextComponent> roles) {

    Collections.sort(roles, new Comparator() {
        public int compare(Object o1, Object o2) {

            int x1 = ((CompanyRole) o1).getBegin();
            int x2 = ((CompanyRole) o2).getBegin();

            if (x1 != x2) {
                return x1 - x2;
            } else {
                int y1 = ((CompanyRole) o1).getEnd();
                int y2 = ((CompanyRole) o2).getEnd();
                return y2 - y1;
            }
        }
    });
}

Теперь список будет отсортирован:)

1
ответ дан 15 August 2018 в 16:43

Либо сделать ActiveAlarm реализовать Comparable<ActiveAlarm>, либо реализовать Comparator<ActiveAlarm> в отдельном классе. Затем вызовите:

Collections.sort(list);

или

Collections.sort(list, comparator);

В общем, рекомендуется реализовать Comparable<T>, если есть один «естественный» порядок сортировки ... в противном случае ( если вам посчастливится сортировать в определенном порядке, но в равной степени легко может понадобиться другой), лучше реализовать Comparator<T>. Эта конкретная ситуация может пойти в любом случае, если честно ... но я, вероятно, придерживаюсь более гибкой опции Comparator<T>.

EDIT: Пример реализации:

public class AlarmByTimesComparer implements Comparator<ActiveAlarm> {
  @Override
  public int compare(ActiveAlarm x, ActiveAlarm y) {
    // TODO: Handle null x or y values
    int startComparison = compare(x.timeStarted, y.timeStarted);
    return startComparison != 0 ? startComparison
                                : compare(x.timeEnded, y.timeEnded);
  }

  // I don't know why this isn't in Long...
  private static int compare(long a, long b) {
    return a < b ? -1
         : a > b ? 1
         : 0;
  }
}
120
ответ дан 15 August 2018 в 16:43
  • 1
    Функция compare () не указана в Long, потому что реализация еще более тривиальна: return a - b; – papercrane 10 January 2014 в 06:33
  • 2
    @papercrane: Нет, это не соответствует причинам переполнения. Рассмотрим a = Long.MIN_VALUE, b = 1. – Jon Skeet 10 January 2014 в 11:06
  • 3
    с API 19 (KitKat) Long теперь имеет .compare – Martin Marconcini 28 April 2016 в 01:41

Другие вопросы по тегам:

Похожие вопросы: