I've been trying to make Map.Entry Comparator in Java8 using lambda expressions and have found a very strange behaviour.
Map<Integer, String> map = new TreeMap<>();
map.put(1, "Hello");
map.put(3, "zzzz");
map.put(2, "aaaa");
map.put(5, "AAAAA");
map.put(4, "aaaa");
Comparator<Map.Entry<Integer, String>> com = Comparator.comparing(Map.Entry::getValue);
com = com.reversed();
Comparator<Map.Entry<Integer, String>> com2 = Comparator.comparing(Map.Entry::getValue).reversed();
com works just fine, but com2 contains a misstake "cannot resolve method getValue". And I really don't know why? Any suggestions?
P.S. Is there any way to avoid typing Map.Entry with Integer, String? Any shorter way?
Since Java-8 there's a standalone method Entry.comparingByValue
which can be used instead:
Comparator<Map.Entry<Integer, String>> com2 =
Map.Entry.<Integer, String>comparingByValue().reversed();
An alternative way to do the same is to pass the parameter:
Comparator<Map.Entry<Integer, String>> com2 =
Map.Entry.comparingByValue(Comparator.reverseOrder());
This way type arguments are unnecessary.
Currently you're specifying the raw type when you specify the method reference - in the first case generic type inference with the assignment tells the compiler what you mean, but that doesn't work for the target of a method call. You can specify the generic type for the method reference though:
Comparator<Map.Entry<Integer, String>> com2 =
Comparator.comparing(Map.Entry<Integer,String>::getValue).reversed();
(I realize that's increasing the number of times you need Map.Entry<Integer, String>
in your code, but unfortunately that's hard to avoid here.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With