2017-02-09 23 views
8

Powiedzmy mam klasy PairJava 8 Komparator porównanie nie łańcuch

public class Pair<P, Q> { 
    public P p; 
    public Q q; 


    public Pair(P p, Q q) { 
     this.p = p; 
     this.q = q; 
    } 

    public int firstValue() { 
     return ((Number)p).intValue(); 
    } 

    public int secondValue() { 
     return ((Number)q).intValue(); 
    } 
} 

I pragnę ją uporządkować, najpierw pierwszej wartości, a następnie przez drugą wartością. Teraz”, jeśli mogę to zrobić

List<Pair<Integer, Integer>> pairList = new ArrayList<>(); 
pairList.add(new Pair<>(1, 5)); 
pairList.add(new Pair<>(2, 2)); 
pairList.add(new Pair<>(2, 22)); 
pairList.add(new Pair<>(1, 22)); 
pairList.sort(Comparator.comparing(Pair::firstValue)); 

Wszystko działa dobrze, lista jest sortowana według pierwszych wartości pary, ale jeśli to zrobię to

pairList.sort(Comparator.comparing(Pair::firstValue).thenComparing(Pair::secondValue)); 

To nie powiedzie się z powodu błędu

Error:(24, 38) java: incompatible types: cannot infer type-variable(s) T,U 
(argument mismatch; invalid method reference 
    method firstValue in class DataStructures.Pair<P,Q> cannot be applied to given types 
    required: no arguments 
    found: java.lang.Object 
    reason: actual and formal argument lists differ in length) 

Ok, więc może nie być w stanie wywnioskować argumentów, więc jeśli to zrobię,

pairList.sort(Comparator.<Integer, Integer>comparing(Pair::firstValue) 
              .thenComparing(Pair::secondValue)); 

To nie powiedzie się z powodu błędu

Error:(24, 39) java: invalid method reference 
non-static method firstValue() cannot be referenced from a static context 

Dlaczego to działa dla porównania(), a nie do porównywania(). ThenComparing()?

+2

Spróbuj 'komparatora comparing'. – shmosel

+0

@shmosel wow, który działał, czy możesz dodać go jako odpowiedź z powodu, dlaczego zadziałało! Dzięki! –

+0

Podejrzewam, że miałbyś mniej problemów, jeśli użyłeś [Comparator.comparingInt] (https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparingInt-java.util.function .ToIntFunction-). – VGR

Odpowiedz

5

Błąd wydaje się być związany z ogólnymi parametrami Pair. Jeden obejście go używać wyraźny typ, jak już próbowali:

pairList.sort(Comparator.<Pair>comparingInt(Pair::firstValue).thenComparingInt(Pair::secondValue)); 
//      ^^^^^^ 

Zanotuj comparingInt() co zmniejsza liczbę parametrów, które należy podać, i poprawia wydajność poprzez unikanie boks.

Innym rozwiązaniem jest parametryzacji oznaczenie typu.

pairList.sort(Comparator.comparingInt(Pair<?,?>::firstValue).thenComparingInt(Pair::secondValue)); 
//          ^^^^^ 
3

Powinno być:

pairList.sort(Comparator.<Pair, Integer>comparing(Pair::firstValue) 
             .thenComparing(Pair::secondValue)); 

Pierwszy parametr typu odnosi się do typu są przekazywane do komparatora. Parametr drugiego typu odnosi się do typu, z którym porównawca powinien efektywnie się porównywać.