web-dev-qa-db-fra.com

Comment obtenir l'élément max () de la liste dans la goyave

Disons que nous avons une collection d'articles:

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

List<Item> list = getListOfItems();

Je voudrais obtenir un article avec un prix maximum de cette liste avec la bibliothèque de goyave (avec Commande , je présume). Je veux dire quelque chose de similaire à ce code Groovy:

list.max{it.price}

Comment je fais ça? Est-il efficace?

37
Mike Minicki
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);

C'est aussi efficace que possible: il parcourt les éléments de la liste et renvoie le premier des éléments ayant le prix maximum: O (n).

58
JB Nizet

Selon la réponse de JB, vous pouvez également utiliser un raccourci lorsque vous travaillez avec des valeurs qui ont un ordre naturel, par exemple:

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

Voir Ordering.natural () pour plus de détails.

37
Marcin Kubala

Vous pouvez le faire sans goyave.

Collections fournit des méthodes min et max qui fonctionnent sur n'importe quelle collection, y compris des surcharges prenant des comparateurs. Ici, nous utilisons les méthodes statiques du comparateur Java 8 avec un lambda pour spécifier de manière concise un comparateur, mais avant Java 8, vous pouvez utiliser une classe anonyme:

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

Ces méthodes lèveront NoSuchElementException si la collection est vide.


Les flux Java 8 fournissent des fonctions min et max prenant un comparateur. Ces fonctions renvoient Optional<T> pour gérer avec élégance le flux vide. Les méthodes statiques de Comparator sont utiles pour spécifier de manière concise les comparateurs, y compris le cas commun de l'ordre naturel. Pour cette question, vous utiliseriez

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

Cela fonctionnera pour n'importe quelle source de flux, qui comprend toutes les implémentations de collection, ainsi que d'autres choses comme les fichiers, et facilite le calcul du maximum d'un sous-ensemble d'une collection en filtrant le flux. Si vous avez une grande collection et un comparateur coûteux (par exemple, l'ordre naturel de String), vous pouvez utiliser un flux parallèle.

(À part: idéalement, Stream fournirait des surcharges min et max sans argument lorsque le type de flux implémente Comparable. Malheureusement Java ne prend pas en charge les méthodes d'exposition conditionnelles basées sur sur un paramètre de type, et cela ne vaut pas la peine d'introduire une nouvelle interface StreamOfComparable étendant Stream juste pour ce cas.)

14
Jeffrey Bosboom