A Set
не имеет API для изменения порядка. Вы заметите себя, если попытаетесь, например, поменять местами первый и второй элементы Set
.
. Кроме того, у наборов есть свои контракты, касающиеся порядка, который будет нарушен, если вы сможете изменить его извне
HashSet
и набор ключей HashMap
не поддерживают порядок вообще. Это общее предположение для наборов, если не указан другой контракт LinkedHashSet
, а набор ключей LinkedHashMap
будет отражать порядок вставки TreeSet
и набор ключей TreeMap
используйте естественный порядок ключей или порядок явно определенного компаратора. Все реализации SortedSet
связаны с Comparator
или естественным порядком ключей.
Для сортировки чего-либо вам нужна коллекция, которая поддерживает порядок и имеет API, поддерживающий изменение заказ.
A List
является естественным кандидатом. Вы также можете сортировать массивы. Поскольку LinkedHashMap
отражает порядок вставки, вы можете создать LinkedHashMap
с указанным c порядком, добавив элементы в нужном порядке:
map = map.entrySet().stream()
.sorted(Map.Entry.<String,Integer>comparingByValue().reversed()
.thenComparing(Map.Entry::getKey))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a,b)->b, LinkedHashMap::new));
Кроме того, ваш компаратор выглядит испорченным. Термин map.get(b) - map.get(a)
указывает, что значения являются числовыми, в приведенных выше примерах я предположил Integer
, но map.get(a) == map.get(b)
сравнивает ссылки объектов в штучной упаковке.
И в случае Integer
, разница map.get(b) - map.get(a)
может переполниться. Вместо этого следует использовать Integer.compare(map.get(b), map.get(a)
.
Или использовать фабричные методы для компараторов, когда это применимо
List<String> words = new ArrayList<>(map.keySet());
words.sort(Comparator.<String>comparingInt(map::get).reversed()
.thenComparing(Comparator.naturalOrder()));