2016-08-18 4 views
-2

リストのLocalDateまたはList of Date型のいずれかをとり、リストの最大値を返すジェネリックメソッドfindMax(リストリスト)を作成しようとしています。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)); 

} 

ですEDITED: はそれが

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()

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

から変更することで動作するようになりました

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日] |最大:compareToメソッドを実装する必要がありComparableインターフェイスを実装

どれでもクラスを比較すると、2016年8月20日

。このオブジェクトは、同じ型の別のオブジェクトよりも小さい、等しい、または大きいので、このメソッドは負の整数、ゼロ、または正の整数を返す必要があります。

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との互換性を維持するために、消去の下で型が強制的に 'Object'であるようにすることです。 –

関連する問題