Сортировка коллекций с пользовательским компаратором не работает - PullRequest
4 голосов
/ 06 августа 2011

Я создал собственный компаратор для сортировки ArrayList of Strings.Я запустил его через отладчик и смотрел, как он сравнивает и возвращает значения правильно.Однако мой массив не отсортирован.Поскольку я новичок в Java и Android, возможно, что-то еще происходит.

После нескольких часов просмотра я не могу понять, что ... и поскольку я использую этот сайт дляответить на многие другие вопросы, я знал, куда идти!

    Collections.sort(allWords, new Comparator<String>(){
        public int compare(String o1, String o2) {
            scoreWord sc1 = new scoreWord((String)o1);
            scoreWord sc2 = new scoreWord((String)o2);
            int i1 = sc1.getScore();
            int i2 = sc2.getScore(); 
            if ( i1 > i2 )
                return 1;
            return 0;
        }

        public boolean equals(String o1, String o2) {
            scoreWord sc1 = new scoreWord((String)o1);
            scoreWord sc2 = new scoreWord((String)o2);
            int i1 = sc1.getScore();
            int i2 = sc2.getScore(); 
            if ( i1 == i2 )
                return true;
            return false;
        }
     });

Ответы [ 3 ]

20 голосов
/ 06 августа 2011

Ваш compare метод не является симметричным - он всегда либо возвращает 1 или 0.

Вместо этого просто делегируйте Integer.compare (если он доступен в версии Javaвы используете), передавая баллы:

public int compare(String o1, String o2) {
    scoreWord sc1 = new scoreWord((String)o1);
    scoreWord sc2 = new scoreWord((String)o2);
    return Integer.compare(i1, i2);
}

В противном случае сделайте это вручную, что, откровенно говоря, является болью - если вам это нужно в нескольких местах, я предлагаю вам написать свою собственную реализациюInteger.compare, чтобы избежать повторения:

public int compare(String o1, String o2) {
    scoreWord sc1 = new scoreWord((String)o1);
    scoreWord sc2 = new scoreWord((String)o2);
    return i1 > i2 ? 1
         : i1 < i2 ? -1
         : 0;
}

Таким образом, вы получите соответствующую симметрию:

  • a.compareTo(b) < 0 подразумевает b.compareTo(a) > 0
  • a.compareTo(b) > 0 подразумевает b.compareTo(a) < 0
  • a.compareTo(b) == 0 подразумевает b.compareTo(a) == 0
12 голосов
/ 06 августа 2011

Попробуйте это:

   public int compare(String o1, String o2) {
        scoreWord sc1 = new scoreWord((String)o1);
        scoreWord sc2 = new scoreWord((String)o2);
        int i1 = sc1.getScore();
        int i2 = sc2.getScore(); 
        if ( i1 > i2 ) {
            return 1;
        } else if ( i1 < i2 ) {
            return -1;
        } else {
            return 0;
        }
    }
2 голосов
/ 06 августа 2011

Ваш компаратор должен возвращать что-то похожее на:

Return: отрицательное целое число, ноль или положительное целое число, поскольку первый аргумент меньше, равен или больше, чемсекунда.

Источник

...