2012-08-01 11 views
37

Lassen Sie uns bekommen, wir haben eine Sammlung von Gegenständen haben:Wie max() Element von Liste in Guava

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

List<Item> list = getListOfItems(); 

Ich möchte einen Artikel mit einem maximalen Preis bekommen aus dieser Liste mit Guava-Bibliothek (mit Ordering, nehme ich an). Ich meine etwas ähnliches zu diesem Groovy-Code:

list.max{it.price} 

Wie mache ich das? Wie effizient ist das?

Antwort

55
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); 

Es ist so effizient, wie es sein kann: es durch die Elemente der Liste iteriert, und gibt die erste der Artikel den Höchstpreis mit: O (n).

+0

wenn der Preis nicht int ist. Sind Sie in Guava-Art, diesen Ansatz zu verwenden? – gstackoverflow

+0

Die Art des Preises ist irrelevant. Sie müssen nur eine Bestellung angeben, die Artikel nach Preis vergleicht. Nehmen wir an, es ist BigDecimal, Sie würden 'return left.price.compareTo (right.price)' verwenden. –

34

Nach JB Antwort, können Sie auch einige Kurzschrift verwenden, wenn mit Werten arbeiten, die natürliche Ordnung haben, zum Beispiel:

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

Siehe Ordering.natural() für weitere Einzelheiten.

11

Sie können dies ohne Guava tun.

Collections bietet min und max Methoden, die auf jeder Sammlung funktionieren, einschließlich Überladungen unter Verwendung von Komparatoren. Hier verwenden wir die Java 8 Vergleicher statische Methoden mit einem Lambda knapp einen Komparator angeben, aber vor Java 8 können Sie eine anonyme Klasse verwenden:

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

Diese Methoden NoSuchElementException werfen, wenn die Sammlung leer ist.


Java 8 Ströme liefern min und max Funktionen einen Komparator nehmen. Diese Funktionen geben Optional<T> zurück, um den Strom, der leer ist, ordnungsgemäß zu behandeln. Die statischen Methoden in Comparator eignen sich zum präzisen Festlegen von Komparatoren, einschließlich des allgemeinen Falls der natürlichen Reihenfolge. Bei dieser Frage würden Sie verwenden

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

Dies ist für jede Stromquelle arbeiten, die alle Sammlung Implementierungen enthält, sowie andere Dinge, wie Dateien und machen es einfach, die max eine Teilmenge von a zu berechnen Sammlung durch Filtern des Streams. Wenn Sie eine große Sammlung und einen teuren Vergleicher haben (z. B. die natürliche Reihenfolge von String), können Sie einen parallelen Stream verwenden.

(abgesehen. Idealerweise Strom würde min und max Überlastungen kein Argument zu nehmen, wenn der Stream-Typ implementiert Comparable Leider Java unterstützt keine bedingt Methoden basierend auf einem Typ-Parameter Belichtung, und es lohnt sich nicht, eine neue StreamOfComparable Einführung Interface extending Stream nur für diesen Fall.)