Непонимание о компараторе в java 8
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;
}
}
Хорошо, как вы поняли, этот код печатает мои пары ключей из самого низкого значения, связанного с самым высоким, поэтому я получаю ожидаемый результат:
3
1
2
Пока все хорошо. Теперь я хотел сделать обратное, я думал, что мне нужно будет только
list.stream()
.sorted(Comparator.comparingInt(p -> p.v).reversed())
.map(p -> p.k)
.forEach(System.out::println);
Но я получаю ошибку компиляции:
v cannot be resolved or is not a field
Итак, кажется, что comparingInt
возвращает Comparator<Object>
. Почему это так? Если он не возвращает a Comparator<Integer>
?
Они оба воспроизводятся с Eclipse Luna версии 1 и javac.
javac -version => 1.8.0
java -version => java version "1.8.0_25"
О, также не стесняйтесь менять заголовок моего вопроса, вы находите его слишком общим, но я не мог найти правильные условия
Ответы
Ответ 1
Я считаю, что это просто вывод типа, в основном - потому что вызов reverse()
мешает ожидаемому типу аргумента sorted()
и выражению лямбда.
Вы можете сделать это, если явно указать тип comparingInt
:
list.stream()
.sorted(Comparator.<Pair<String, Integer>>comparingInt(p -> p.v).reversed())
.map(p -> p.k)
.forEach(System.out::println);
Или, если вы сначала объявите компаратора:
Comparator<Pair<String, Integer>> forward = Comparator.comparingInt(p -> p.v);
list.stream()
.sorted(forward.reversed())
.map(p -> p.k)
.forEach(System.out::println);
Мне кажется, что должен быть Stream.reverseSorted
, поэтому сделать это очень просто, но он не выглядит так: (