2014-11-29 2 views
12
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; 
    } 
} 

Хорошо, как вы поняли этот код печатают ключи паров от минимального значения, связанного с самым высоким, поэтому я получить ожидаемый результат:Непонимания о Компараторе в Java 8

Пока все хорошо. Теперь я хотел бы сделать наоборот, я думал, что только сделать

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>. Почему это так? Разве он не должен возвращать Comparator<Integer>?

Они оба воспроизводятся с Eclipse Luna версии 1 и javac.

javac -version => 1.8.0 
java -version => java version "1.8.0_25" 

О, не стесняйтесь, чтобы изменить название моего вопроса вы находите это слишком общий характер, но я не мог найти правильные термины

+0

Возможно, это будет работать с Comparator.reverseOrder. – assylias

+0

@assy lias Хорошо, как бы я мог добиться этого с помощью reverseOrder? Это означало бы, что мои парные объекты уже сопоставимы. – user2336315

+0

Отвечено здесь: http://stackoverflow.com/questions/25172595/comparator-reversed-not-compiles-using-lambda –

ответ

8

Я считаю, что это просто, что определение типа не удается, в основном - потому что вызов 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 так что сделайте такую ​​вещь очень простой, но она не выглядит так :(

+0

... что довольно уродливо, тогда я предпочитаю использовать 'sorted ((p1, p2) -> p2.v.compareTo (p1.v))'. Значит, это скорее ошибка в компиляторе? – user2336315

+4

@ user2336315: Я согласен, что это уродливо - но это не значит, что это ошибка в компиляторе. Я считаю, что это ограничение типа вывода на языке, что не то же самое. Честно говоря, я никогда полностью не понимал, как работает типичный вывод типа в Java (и я считаю, что он изменился в нескольких местах с течением времени), но это определенно кажется простым ограничением для меня. –

+0

А я вижу. Возможно, в будущем выпуске это будет улучшено. Я знаю, что они сделали некоторые улучшения, поэтому я понял, что было странно, что он не компилировался ... :( – user2336315

Смежные вопросы