Как treemap обрабатывает случай помещения ключа в тот же индекс?

#java #algorithm #binary-search-tree #treemap

#java #алгоритм #двоичное дерево поиска #treemap

Вопрос:

Я попробовал следующий код:

 public static void main (String[] args) throws java.lang.Exception
{
   // sorting based on number of dots
    Map<String, String> map =new TreeMap<>((o1, o2) -> {
        int noOfDots1 = o1.length() - o1.replaceAll("\.", "").length() ;
        int noOfDots2 = o2.length() - o2.replaceAll("\.", "").length() ;
        return noOfDots1 - noOfDots2;
    });
    map.put("ty.r.r.r", "a");
    map.put("t.i.o", "b");
    map.put("i.o.y.y", "c");
    map.put("p.u.r.w.e", "d");
    map.put("j.k.i", "e");
    System.out.println(map);
}
 

Но вывод поступает следующим образом :

 {t.i.o=e, ty.r.r.r=c, p.u.r.w.e=d}
 

Почему мы не получаем все пять ключей на выходе?

Редактировать :

Спасибо всем, я понял, почему я не получаю все 5 ключей на выходе, но мне просто интересно, как лучше всего получить все ключи в отсортированном порядке точек.

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

Ответ №1:

Поскольку количество точек в ключах равно :

 3
2
3
4
2
 

Уникальные показатели : 2, 3 and 4

Комментарии:

1. Это причина уникальности, как определено его компаратором. Равные точки переводятся в одно и то же значение ключа.

2. Извините, неправильно понял ваш язык. Я думал, вы утверждали, что ключи — это количество точек 1.

3. Спасибо @SauravSahu, теперь я понял, как лучше всего отсортировать эту карту на основе точек, чтобы я мог также получить все данные в выходных данных.

Ответ №2:

put Метод в TreeMap использует указанный вами компаратор для проверки равенства. Если ваш компаратор возвращает 0 два ключа, он считает их идентичными.

Для ваших данных это означает, что все строки с равным количеством точек считаются идентичными ключами.

Соответствующий источник: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/TreeMap.java#L795

Ответ №3:

.replace(".", "") строго превосходит (replace также заменяет все вхождения; он просто не использует регулярные выражения. Вы должны исправить эту часть своего кода).

Простое решение — иметь вторичный порядок сортировки. Как должны сортироваться t.i.o и j.k.y относительно друг друга? Например, если вы хотите алфавитный:

 Comparator<String> a = (o1, o2) -> 
  o1.length() - o1.replace(".", "").length() -
  (o2.length() - o2.replace(".", "").length());

Comparator<String> b = Comparator.naturalOrder();

var map = new TreeMap<String, String>(a.thenComparing(b));
 

Обратите внимание на использование ‘thenComparing’ для установления вторичного порядка сортировки, который будет использоваться, когда первый в противном случае приведет к равенству.