2017-02-02 44 views
3

我有以下類:如何獲得Comparator.comparing正確推斷類型參數?

import java.util.ArrayList; 
import java.util.Comparator; 
import java.util.List; 

import org.apache.commons.lang3.tuple.Pair; 

public class Sorter { 
    private List<Pair<Long, NameDTO>> dtoPairs = new ArrayList<>(); 

    public Sorter() { 
     Comparator<Pair<Long, NameDTO>> bySize = Comparator.comparing(Pair::getLeft); 
     Comparator<Pair<Long, NameDTO>> byName = Comparator.comparing(p -> p.getRight().getName()); 
     dtoPairs.sort(bySize.reversed().thenComparing(byName)); 
    } 
} 

class NameDTO { 
    private String name; 
    public String getName() { 
     return name; 
    } 
} 

這將編譯沒有問題。但是,如果我嘗試內聯變量是這樣的:

dtoPairs.sort(Comparator.comparing(Pair::getLeft).reversed().thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 

我得到以下編譯錯誤:

Sorter.java:[18,51] incompatible types: cannot infer type-variable(s) T,U 
    (argument mismatch; invalid method reference 
     method getLeft in class org.apache.commons.lang3.tuple.Pair<L,R> cannot be applied to given types 
     required: no arguments 
     found: java.lang.Object 
     reason: actual and formal argument lists differ in length) 

我怎麼能寫這樣的表達使Java正確理解的參數?

+0

的[對比和thenComparing給出編譯錯誤]可能的複製(http://stackoverflow.com/questions/40500280/comparing-and-thencomparing-gives-compile-error) –

+1

@ OleV.V:我不知道認爲這是重複的,它沒有泛泛的方法參考,這是什麼扔我在這裏。 – Keppil

回答

3

您需要告訴編譯器通用參數的類型。 試試這個:

dtoPairs.sort(
    Comparator.comparing(Pair<Long, NameDTO>::getLeft) 
    .reversed() 
    .thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 
+0

啊,很酷,我沒有看到這種方法的參考語法。 '(Pair )p'顯然不需要,我所需要的就是'Pair :: getLeft'調整。 – Keppil

+0

沒錯。我只是添加了它,以便更清楚。我從我的答案中刪除了它。 –

2

本聲明編譯就好:

dtoPairs.sort(Comparator.comparing((Pair<Long, NameDTO> p) -> p.getLeft()) 
         .reversed() 
         .thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 

...這指出了爲什麼你不能編譯的原因:當你這樣做的方法引用(Pair:getLeft),Pair是原始的,它的類型參數被忽略。這使thenComparing(...)方法預計Comparator<Pair, Object>