В Java сортируйте хэш-карту по ее ключу.длина()

у меня есть hashmap, как это:

HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("java",4);
map.put("go",2);
map.put("objective-c",11);
map.put("c#",2);

теперь я хочу отсортировать эту карту по длине ключа, если длина двух ключей равна (e.G go и c# обе длины 2), затем сортируются по порядку alphba. таким образом, результат, который я ожидаю получить, что-то вроде:

результат печати: цель-с, 11 java, 4 в C#, 2 пойти, 2

вот мой собственный аттамп, но он не работает вообще...

      HashMap<String,Integer> map = new HashMap<String,Integer>();
          map.put("java",4);
          map.put("go",2);
          map.put("objective-c",11);
          map.put("c#",2);

      Map<String,Integer> treeMap = new TreeMap<String, Integer>(
                new Comparator<String>() {
                    @Override
                    public int compare(String s1, String s2) {
                        return s1.length().compareTo(s2.length());
                    }
                }
        );

на самом деле метод "compareTo" отображается красным цветом (не может составлять.)... пожалуйста, кто-нибудь помогите мне с некоторым примером кода...я немного путаю с тем, как использовать класс comparator для настройки объекта сравнения...

6 ответов


компилятор жалуется, потому что вы не можете назвать compareTo на int. Правильный способ сортировки карты заключается в следующем:

Map<String, Integer> treeMap = new TreeMap<String, Integer>(
    new Comparator<String>() {
        @Override
        public int compare(String s1, String s2) {
            if (s1.length() > s2.length()) {
                return -1;
            } else if (s1.length() < s2.length()) {
                return 1;
            } else {
                return s1.compareTo(s2);
            }
        }
});

первые два условия сравнивают длины двух Strings и возвращают положительное или отрицательное число соответственно. Третье условие будет сравнивать Strings лексикографически, если их длины равны.


вы называете String#length(), который возвращает примитивное int. Вам нужен статический метод Integer.compare(int,int). Если вы находитесь на Java 8, вы можете сэкономить много печатать:

Map<String,Integer> treeMap = new TreeMap<>(
        Comparator.comparingInt(String::length)
                  .thenComparing(Function.identity()));

, потому что length() не определяет compareTo способ thats, почему вы видите ошибку. Чтобы исправить это, используйте Integer.compare(s1.length(), s2.length()); обновленный код ниже

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Test {

    public static void main(String[] args) {

        HashMap<String,Integer> map = new HashMap<String,Integer>();
        map.put("java",4);
        map.put("go",2);
        map.put("objective-c",11);
        map.put("c#",2);


        Map<String,Integer> treeMap = new TreeMap<String, Integer>(
                new Comparator<String>() {
                    @Override
                    public int compare(String s1, String s2) {
                        return Integer.compare(s1.length(), s2.length());
                    }
                }
        );

        treeMap.putAll(map);

        System.out.println(treeMap);
    }
}

при использовании TreeMap и Не обязательно

Explantion определение Comaprator, и следующий шаг, Определите список, чтобы мы могли добавить все записи карты в список. В конце отсортируйте список по defined Comaprator

код:

 Comparator<Map.Entry<String,Integer>> byMapValues = 
         (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) ->left.getValue().compareTo(right.getValue());

 List<Map.Entry<String,Integer>> list = new ArrayList<>();
 list.addAll(map.entrySet());
 Collections.sort(list, byMapValues);
 list.forEach( i -> System.out.println(i));

выход:

c#=2
go=2
java=4
objective-c=11

Примечание: сортировка по номеру

если есть необходимость сделать сравнение на основе ключа, можно использовать следующую строку.

Comparator<Map.Entry<String,Integer>> byMapKeys = 
             (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey());

        public int compare(String o1, String o2) {
            return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length();
        }

компаратор должен быть:

new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
    }
}