у меня есть
Map<String,LongAdder>
и я хочу сортировать по значению наилучшим образом в потоках. Это сложнее, чем с Long, потому что LongAdder не реализует Comparable, поэтому мне приходится использовать longValue (или intValue, если для создания компаратора используется вычитание).
я знаю, что могу использовать
m.entrySet().stream().sorted((a, b) -> b.getValue().intValue() - a.getValue().intValue())
но на самом деле я хочу также сортировать по ключу (String). Я также сортирую в обратном порядке.
я хочу делать
m.entrySet().stream().sorted(
Comparator.comparing((a, b) -> b.getValue().intValue() - a.getValue().intValue()))
так что я могу потом связать больше компараторов с thenComparing()
Исключением является
Lambda expression's signature does not match the signature of the functional interface method apply(T)
Но даже объявление автономного компаратора не работает:
Comparator<Map.Entry<String,LongAdder>> byCount = Comparator.comparing((a,b) ->
(b.getValue().intValue() - a.getValue().intValue()));
Lambda expression's signature does not match the signature of the functional interface method apply(T)
Я не могу использовать функциональную ссылку "::", потому что это слишком много частей: Map.Entry.getValue().intValue().




Ваш автономный компаратор может быть исправлен для использования Function и будет выглядеть так:
Comparator<Map.Entry<String,LongAdder>> byCount = Comparator.comparingInt(e -> e.getValue().intValue());
Comparator.comparingLong - это то, что вам нужно:
Comparator<Map.Entry<String, LongAdder>> byCount =
Comparator.comparingLong((Map.Entry<String, LongAdder> e) ->
e.getValue().longValue()).reversed().thenComparing(...);
Важное примечание: не забудьте использовать явно типизированное лямбда-выражение, иначе цепочка методов типа comparing(...).thenComparing(...) не будет компилироваться в данном конкретном случае1.
1 - This answer explains why.
На одном уровне вы можете избежать явных типов при использовании Comparator<Map.Entry<String, LongAdder>> byCount = Map.Entry.comparingByValue(Comparator.comparingLong(LongAdder::sum).reversed( )); Но при цепочке других критериев сортировки вам в конечном итоге понадобятся явные типы, например Comparator<Map.Entry <String, LongAdder>> byCount2 = Map.Entry.<String, LongAdder>comparingByValue(Comparator. comparingLong(LongAdder::sum).reversed()).thenComparing(…);
Comparator.comparingне принимаетComparator— он принимает функцию, которая отображает ваш объект в сопоставимый. Кроме того, никогда не используйте вычитание для сравнения — оно может переполниться и дать вам неверный результат. ИспользуйтеInteger.compare. Кроме того, не используйтеintValue, если ваши числа на самом деле длинные — опять же, вы потеряете информацию.