#groovy
#groovy
Вопрос:
Я написал приведенный ниже пример поиска min
элемента во вложенном List<List<String>>
, который отлично работает:
List<String> el0 = ["112", "2"]
List<String> el1 = ["11", "222", "45", "1"]
List<String> el2 = ["21", "112", "23"]
List<List<String>> container = new ArrayList<>()
container << el0
container << el1
container << el2
List<String> candidates = container.collect { it.min(new Comparator<String>() {
@Override
int compare(String o1, String o2) {
return Integer.valueOf(o1) <=> Integer.valueOf(o2)
}
}) }
String min = candidates.min()
println (min)
Но есть ли оптимизация / упрощение, которые можно выполнить для приведенного выше довольно подробного примера — предполагая, что элементы должны быть строками (и в будущем более сложными объектами)?
Ответ №1:
Упрощенный способ позволяет найти минимальный элемент за одну операцию после выравнивания container
(минимальное уменьшение выполняется только один раз). Это может выглядеть так:
String min = container.flatten().min{Integer.valueOf(it)}
Как видно, я также использовал {Integer.valueOf(it)}
в качестве замыкания для реализации Comparator<String>
, что вы сделали, используя анонимный класс.
Комментарии:
1. Другой вариант
List<String> candidates = container*.min {Integer.valueOf(it) }
2. @tim_yates Я бы ожидал, что это приведет к созданию списка с минимальным значением в каждом подсписке… Если
min()
в результате не вызывается другой:container*.min{Integer.valueOf(it)}.min{Integer.valueOf(it) }
3. Да, я имел в виду с оригиналом
String min = candidates.min()
, как в вопросе 😉4. Что делает контейнер *? И как называется этот «оператор»? Я пытался найти его в Google, но не нашел никаких совпадений
5. @u123 Это оператор распространения (или оператор с расширенной точкой)
*.
. Документация здесь . Он вызывает метод после точки на каждом элементе коллекции, к которой он применяется, создавая новую коллекцию с результатом каждого вызова; как в[1,2,3,4]*.plus(2) == [3, 4, 5, 6]