Использование нескольких компараторов для сортировки списка строк несколько раз

1

Я пытаюсь группировать строки, игнорируя случаи, присутствующие в списке, и снова пытаюсь их отсортировать с учетом чувствительности к регистру.

Итак, если у меня есть входные данные следующим образом:

"Abc","DEF","abc","dEf"

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

"Abc","abc","DEF","dEf"

и второй уровень должен быть:

"abc","Abc","dEf","DEF"

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

public class ListSortIgnoreCaseComparator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<String> input = new ArrayList<>();
        input.add("Abc");
        input.add("DEF");
        input.add("abc");       
        input.add("dEf");
        System.out.println("Input: "+input);

        Collections.sort(input, new GroupIgnoreCase());
        System.out.println("Output: "+input);
    }
}

/**
 * 
 * @author 
 *
 */
class GroupIgnoreCase implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {      
        return s1.compareToIgnoreCase(s2);
    }

}
/**
 * 
 * @author 
 *
 */
class SortIgnoreCase implements Comparator<String> {

    @Override
    public int compare(String s3, String s4) {
        if(s3.equalsIgnoreCase(s4)){
            return s3.compareTo(s4);
        }
        return 0;
    }
}

И выход выглядит следующим образом:

Input: [Abc, DEF, abc, dEf]
Output: [Abc, abc, DEF, dEf]

Можем ли мы настроить "Компаратор" таким образом, чтобы выход:

Output: [abc, Abc, dEf, DEF]

вместо выше?

  • 0
    Вы пробовали использовать вместо этого Collator ?
  • 0
    @assylias Collator, Collator , мощный, но пишет свой, если не тот, который вам нужен, э-э
Показать ещё 1 комментарий
Теги:
sorting
collections
comparator

3 ответа

4
Лучший ответ

Да, вы можете сравнить их, игнорируя случай, и только если они равны, вы должны сравнить их снова, на этот раз не игнорируя случай:

@Override
public int compare(String s1, String s2) {      
    int cmp = s1.compareToIgnoreCase(s2);
    if (cmp == 0)
        cmp = s1.compareTo(s2);
    return cmp;
}
  • 0
    Как это может быть? Ваш метод compare() прежнему возвращает выходные Output: [Abc, abc, DEF, dEf] . Пожалуйста, проверьте это дважды.
  • 0
    @Antony Ну, мой ответ показывает, как «разорвать связь» для строк, которые равны на основе сравнения без учета регистра. В чувствительном к регистру лексикографическом порядке буквы нижнего регистра идут после букв верхнего регистра. Если строчные буквы должны предшествовать заглавным буквам, обратный порядок поможет - s2.compareTo(s1) .
2

Используйте Collator с силой TERTIARY:

public class ListSortIgnoreCaseComparator {

    /**
     * @param args
     */
    public static void main(String[] args) {
        List<String> input = new ArrayList<>();
        input.add("Abc");
        input.add("DEF");
        input.add("abc");       
        input.add("dEf");
        System.out.println("Input: "+input);

        Collator c = Collator.getInstance();
        c.setStrength(Collator.TERTIARY);

        Collections.sort(input, c);
        System.out.println("Output: "+input);
    }
}

Дальнейшее чтение: Сравнение строк (Учебники Java > Интернационализация> Работа с текстом)

1

Это мое решение:

@Override
public int compare(String s1, String s2) {
    int comVal = s1.compareToIgnoreCase(s2);
    if (comVal == 0) {
        return s2.compareTo(s1);
    } else {
        return comVal;
    }
}

Input: [Abc, DEF, abc, dEf]
Output: [abc, Abc, dEf, DEF]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню