38

アイテムのコレクションがあるとしましょう:

class Item {
    public String title;
    public int price;
}

List<Item> list = getListOfItems();

Guava ライブラリを使用して、そのリストから最大価格のアイテムを取得したいと思います ( Orderingを使用すると思います)。このGroovyコードに似たものを意味します:

list.max{it.price}

それ、どうやったら出来るの?どのくらい効率的ですか?

4

3 に答える 3

59
Ordering<Item> o = new Ordering<Item>() {
    @Override
    public int compare(Item left, Item right) {
        return Ints.compare(left.price, right.price);
    }
};
return o.max(list);

これは可能な限り効率的です。リストのアイテムを繰り返し処理し、最大価格 O(n) を持つ最初のアイテムを返します。

于 2012-08-01T12:18:51.660 に答える
38

JB の回答によると、自然な順序を持つ値を操作するときに、省略形を使用することもできます。たとえば、次のようになります。

Ordering.<Integer> natural().max(listOfIntegers);

詳細については、 Ordering.natural()を参照してください。

于 2013-01-10T12:43:20.347 に答える
16

グアバなしでこれを行うことができます。

Collections は、コンパレータを使用するオーバーロードを含む、任意の Collection で動作するメソッドを提供minします。maxここでは Java 8 Comparator の静的メソッドをラムダで使用してコンパレータを簡潔に指定しますが、Java 8 より前では匿名クラスを使用できます。

Item max = Collections.max(list, Comparator.comparingInt(i -> i.price));

コレクションが空の場合、これらのメソッドは NoSuchElementException をスローします。


Java 8 ストリームは、コンパレータを使用する関数を提供minします。maxこれらの関数Optional<T>は、空のストリームを適切に処理するために戻ります。Comparator の静的メソッドは、自然順序付けの一般的なケースを含め、コンパレータを簡潔に指定するのに役立ちます。この質問では、次を使用します

Optional<Item> max = list.stream().max(Comparator.comparingInt(i -> i.price));

これは、すべての Collection 実装やファイルなどの他のものを含む任意のストリーム ソースで機能し、ストリームをフィルタリングすることでコレクションのサブセットの最大値を簡単に計算できます。大規模なコレクションと高価なコンパレータ (たとえば、String の自然順序付け) がある場合は、並列ストリームを使用できます。

(余談: ストリーム型が Comparable を実装する場合、理想的には、Stream は引数をとらないオーバーロードを提供minmaxます。残念ながら、Java は型パラメーターに基づいて条件付きでメソッドを公開することをサポートしていないため、このためだけに Stream を拡張する新しい StreamOfComparable インターフェイスを導入する価値はありません。場合。)

于 2014-09-23T15:02:26.683 に答える