public class Test {
public static void main(String[] args) {
List<Pair<String, Integer>> list = new ArrayList<>();
list.add(new Pair<>("1", 8));
list.add(new Pair<>("3", 2));
list.add(new Pair<>("2", 15));
list.stream()
.sorted(Comparator.comparingInt(p -> p.v))
.map(p -> p.k)
.forEach(System.out::println);
}
}
class Pair<K, V> {
K k;
V v;
public Pair(K k, V v) {
this.k = k;
this.v = v;
}
}
Ok, as you understood this code is printing my pair keys from the lowest value associated to the highest so I get the expected output:
3 1 2
So far so good. Now I wanted to do the reverse, I thought I would only have to do
list.stream()
.sorted(Comparator.comparingInt(p -> p.v).reversed())
.map(p -> p.k)
.forEach(System.out::println);
But I get a compilation error:
v cannot be resolved or is not a field
So it seems like comparingInt
is returning a Comparator<Object>
. Why it so? Shouldn't it return a Comparator<Integer>
?
These are both reproductible with Eclipse Luna version 1 and javac.
javac -version => 1.8.0
java -version => java version "1.8.0_25"
Oh also feel free to change the title of my question is you find it too general, but I couldn't find the correct terms
I believe it's just that type inference is failing, basically - because the reverse()
call gets in the way of the expected argument type of sorted()
and the lambda expression.
You can do it if you specify the type to comparingInt
explicitly:
list.stream()
.sorted(Comparator.<Pair<String, Integer>>comparingInt(p -> p.v).reversed())
.map(p -> p.k)
.forEach(System.out::println);
Or if you just declare the comparer first:
Comparator<Pair<String, Integer>> forward = Comparator.comparingInt(p -> p.v);
list.stream()
.sorted(forward.reversed())
.map(p -> p.k)
.forEach(System.out::println);
It feels to me like there should be a Stream.reverseSorted
so make this sort of thing really easy, but it doesn't look like it exists :(
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