2016-08-18 36 views
-2

我想創建一個泛型方法findMax(List list),它需要LocalDate的List或Date類型的List,並返回列表中的最大值。如何使用collections.max()編寫通用findMax()方法?

Collections.max(List LocalDate)和Collections.max(List Date)都可以很好地工作,但我不知道如何使它返回正確的類型。

不太瞭解比較器如何在Java中工作。

下面是我嘗試

static List<LocalDate> localDateList = new ArrayList<LocalDate>(); 
static List<Date> dateList = new ArrayList<Date>(); 

private <T> T findMax(List<T> list) { 
    return Collections.max(list); 
} 

public static void main(String[] args) throws ParseException, SQLException, JsonProcessingException { 

    localDateList.add(new Date(11 * 86400000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); 
    localDateList.add(new Date(22 * 86400000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); 
    localDateList.add(new Date(3 * 86400000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); 
    localDateList.add(new Date(14 * 86400000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); 
    localDateList.add(new Date(65 * 86400000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); 

    dateList.add(new Date(11 * 86400000)); 
    dateList.add(new Date(22 * 86400000)); 
    dateList.add(new Date(3 * 86400000)); 
    dateList.add(new Date(14 * 86400000)); 
    dateList.add(new Date(65 * 86400000)); 

    System.out.println(Collections.max(localDateList)); 
    System.out.println(Collections.max(dateList)); 

    System.out.println(findMax(localDateList)); 
    System.out.println(findMax(dateList)); 

} 

編輯: 得到它由

private <T> T findMax(List<T> list) { 
    return Collections.max(list); 
} 

改變爲工作於

private <T extends Object & Comparable<? super T>> T findMax(List<T> list) { 
    return Collections.max(list); 
} 
+1

'Collections.max'已經返回「正確」類型。例如,'String s = Collections.max(yourListOfString)'將被編譯。 –

+1

發佈的代碼有什麼問題?你爲什麼試圖將Collections.max()包裝成一個完全相同的方法?如果你真的想,爲什麼不使用與Collections.max()完全相同的泛型? –

+0

它告訴你,這是一個對象,因爲類型擦除。泛型類型只在編譯時由編譯器知道,並且只與當時相關。他們儘可能避免不安全的演員。 – HopefullyHelpful

回答

3

Collections.max()

無需編寫您的findMax方法。 Collections.max已經爲你做了。

List<LocalDate> localDates = new ArrayList<> (3); 
LocalDate today = LocalDate.now (ZoneId.of ("America/Montreal")); 
localDates.add (today); 
localDates.add (today.plusDays (2)); 
localDates.add (today.minusDays (4)); 

LocalDate max = Collections.max (localDates); 

轉儲到控制檯。

System.out.println ("localDates: " + localDates + " | max: " + max); 

localDates:[2016年8月18日,2016年8月20日,2016年8月14日] |最大:2016年8月20日

比較

任何類實現Comparable接口必須實現一個compareTo方法。該方法必須返回負整數,零或正整數,因爲此對象小於,等於或大於同一類型的另一個對象。

LocalDate類有這compareTo方法實現。

Collections.max方法循環集合的元素,如List並調用每個對象的compareTo方法。所有這些都是以你的名義完成的,以減輕你編寫這些代碼的煩惱。

泛型

意見認爲問題是真正瞭解Java Generics,大約比較。

以下是實施您的findMax方法的示例。我在OpenJDK項目中遵循了Java 8的Collections.max source code的示例。

正如我上面所說,僅僅將打包電話打到Collections.max沒有生產用途。但它確實是一個很好的使用泛型的實驗性例子。

public <T extends Object & Comparable<? super T>> T findMax (Collection<? extends T> coll) { 
    T maximum = Collections.max (coll); 
    return maximum; 
} 

調用該方法並傳遞上面看到的localDates集合。

System.out.println ("findMax: " + this.findMax (localDates)); 
+0

你有什麼線索爲什麼他們使用Object和Comparable?根據我的理解,任何東西都是一個對象,'T extends Comparable'會直接編譯。我試圖弄清楚。 –

+0

啊我明白了,它是強制類型在擦除下的'對象',以保持與預泛型API的兼容性。 –

相關問題