Ответ
Comparator в TreeMap нужен для того, чтобы задать пользовательский порядок сортировки ключей, отличный от их естественного порядка (заданного Comparable).
Контекст: По умолчанию TreeMap<K, V> сортирует ключи по их естественному порядку, что требует, чтобы класс ключа K реализовывал интерфейс Comparable<K>. Если ключи не реализуют Comparable или вам нужна иная логика сортировки, вы должны передать Comparator в конструктор TreeMap.
Практические причины использования Comparator с TreeMap:
- Ключи не реализуют Comparable. Например, использование массива
int[]в качестве ключа (массивы не реализуютComparable). - Требуется сортировка, отличная от естественной. Например, сортировка строк (
String) без учета регистра или в обратном алфавитном порядке. - Необходимо избежать
ClassCastException. При добавлении вTreeMapключей, не поддерживающих сравнение, будет выброшено исключение.Comparatorрешает эту проблему.
Примеры:
// 1. TreeMap с ключами String, отсортированными без учета регистра
Map<String, Integer> caseInsensitiveMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
// 2. TreeMap с ключами String, отсортированными в обратном порядке
Map<String, Integer> reverseMap = new TreeMap<>(Comparator.reverseOrder());
// 3. TreeMap с пользовательским Comparator для сложных ключей
Comparator<Person> byAgeThenName = Comparator
.comparingInt(Person::getAge)
.thenComparing(Person::getName);
Map<Person, String> customOrderMap = new TreeMap<>(byAgeThenName);
Без переданного Comparator TreeMap будет пытаться использовать compareTo() у ключей, что может привести к ошибке или нежелательному порядку.