Как получить max() из списка в Guava
Скажем, у нас есть коллекция элементов:
class Item {
public String title;
public int price;
}
List<Item> list = getListOfItems();
Я хотел бы получить элемент с максимальной ценой из этого списка с помощью библиотеки Guava (с Ordering, я полагаю), Я имею в виду что-то похожее на этот Groovy код:
list.max{it.price}
Как мне это сделать? Насколько он эффективен?
Ответы
Ответ 1
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).
Ответ 2
В соответствии с ответом JB вы также можете использовать некоторые сокращения при работе со значениями, которые имеют естественный порядок, например:
Ordering.<Integer> natural().max(listOfIntegers);
Подробнее см. Ordering.natural().
Ответ 3
Вы можете сделать это без Guava.
Коллекции предоставляют min
и max
методы, которые работают в любой коллекции, включая перегрузки с компараторами. Здесь мы используем статические методы Java 8 Comparator с лямбдой для краткого указания компаратора, но до Java 8 вы можете использовать анонимный класс:
Item max = Collections.max(list, Comparator.comparingInt(i -> i.price));
Эти методы будут вызывать исключение NoSuchElementException, если коллекция пуста.
Java 8 потоков обеспечивают min
и max
функции, принимающие компаратор. Эти функции возвращают Optional<T>
, чтобы изящно обрабатывать поток, пустой. Статические методы в компараторе полезны для краткого определения компараторов, включая общий случай естественного упорядочения. Для этого вопроса вы должны использовать
Optional<Item> max = list.stream().max(Comparator.comparingInt(i -> i.price));
Это будет работать для любого источника потока, который включает в себя все реализации Collection, а также другие вещи, такие как файлы, и упрощает вычисление максимального количества подмножества коллекции путем фильтрации потока. Если у вас большая коллекция и дорогой компаратор (например, естественный порядок строк), вы можете использовать параллельный поток.
(Кроме того: в идеале Stream обеспечит перегрузки min
и max
без аргументов, когда тип потока реализует Comparable. К сожалению, Java не поддерживает условно разоблачающие методы, основанные на параметре типа, и не стоит вводить новый интерфейс StreamOfComparable, расширяющий Stream только для этого случая.)