Есть ли у guava (или другой java-библиотеки) что-то вроде функции reduce() в Python?
Я ищу что-то вроде http://docs.python.org/library/functions.html#reduce
Есть ли у guava (или другой java-библиотеки) что-то вроде функции reduce() в Python?
Я ищу что-то вроде http://docs.python.org/library/functions.html#reduce
Мне еще не удалось найти библиотеки библиотек Java, поддерживающие map
и reduce
. (Я исключаю функцию map/reduce в параллельных/распределенных инфраструктурах обработки... потому что вам нужна "большая" проблема для этих фреймворков.)
Вероятно, причиной этого "недостатка" является то, что карта/сокращение кодирования без закрытия просто слишком громоздка. Слишком много кода шаблона, слишком сильного сильного веса. Поскольку основной смысл использования примитивов map/reduce в простых коллекциях - сделать ваш код простым и элегантным...
@CurtainDog предоставил ссылку на lambdaj. Это делает то, что происходит после OP (хотя там нет метода, специально называемого reduce
). Но это иллюстрирует то, что я говорил о шаблоне. Обратите внимание, что многие операции более высокого порядка включают создание классов, которые расширяют тот или иной класс Closure
.
(FWIW, я думаю, что методы Lambda.aggregate(...)
являются аналогом lambdaj reduce
.)
Нет. В конце концов, это может быть связано с тем, что функциональный материал не является основным центром Гуавы. См. этот вопрос.
Потоки Java 8 позволяют вам это делать.
mylist.stream().map((x) -> x + 1).reduce((a,b) -> a + b)
Для получения дополнительной информации: http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Недавно я отправил вопрос, где я просил/обсуждал что-то подобное. Это то, что потребуется в моей реализации
/**
* Aggregate the selected values from the supplied {@link Iterable} using
* the provided selector and aggregator functions.
*
* @param <I>
* the element type over which to iterate
* @param <S>
* type of the values to be aggregated
* @param <A>
* type of the aggregated value
* @param data
* elements for aggregation
* @param selectorFunction
* a selector function that extracts the values to be aggregated
* from the elements
* @param aggregatorFunction
* function that performs the aggregation on the selected values
* @return the aggregated value
*/
public static <I, S, A> A aggregate(final Iterable<I> data,
final Function<I, S> selectorFunction,
final Function<Iterable<S>, A> aggregatorFunction){
checkNotNull(aggregatorFunction);
return aggregatorFunction.apply(
Iterables.transform(data, selectorFunction)
);
}
(Функция селектора может вытащить значение для агрегирования из объекта в запрос, но во многих случаях оно будет Functions.identity()
, то есть сам объект является агрегированным)
Это не классическая складка, но для выполнения этой работы требуется Function<Iterable<X>,X>
. Но поскольку фактический код является однострочным, я вместо этого решил запросить некоторые стандартные функции агрегатора (я бы поставил их в класс, называемый как Aggregators
, AggregatorFunctions
или даже Functions.Aggregators
):
/** A Function that returns the average length of the Strings in an Iterable. */
public static Function<Iterable<String>,Integer> averageLength()
/** A Function that returns a BigDecimal that corresponds to the average
of all numeric values passed from the iterable. */
public static Function<Iterable<? extends Number>,BigDecimal> averageOfFloats()
/** A Function that returns a BigInteger that corresponds to the average
of all numeric values passed from the iterable. */
public static Function<Iterable<? extends Number>,BigInteger> averageOfIntegers()
/** A Function that returns the length of the longest String in an Iterable. */
public static Function<Iterable<String>,Integer> maxLength()
/** A Function that returns the length of the shortest String in an Iterable. */
public static Function<Iterable<String>,Integer> minLength()
/** A Function that returns a BigDecimal that corresponds to the sum of all
numeric values passed from the iterable. */
public static Function<Iterable<? extends Number>,BigDecimal> sumOfFloats()
/** A Function that returns a BigInteger that corresponds to the integer sum
of all numeric values passed from the iterable. */
public static Function<Iterable<? extends Number>,BigInteger> sumOfIntegers()
(Вы можете увидеть мои примеры реализации в проблеме)
Таким образом, вы можете делать такие вещи:
int[] numbers = { 1, 5, 6, 9, 11111, 54764576, 425623 };
int sum = Aggregators.sumOfIntegers().apply(Ints.asList(numbers)).intValue();
Это определенно не то, о чем вы просите, но во многих случаях это будет проще, и будет перекрываться с вашим запросом (даже если подход отличается).
Jedi имеет reduce. Джедай также помогает уменьшить плиту котла, используя аннотации для создания функторов для вас. Смотрите examples.
Guava имеет transform (карта). Кажется, что сокращение отсутствует, хотя?
Используйте Полностью ленивый, он реализует все эти вещи еще больше. Он в основном скопировал весь функциональный подход из Clojure.
Я разработал библиотеку для создания карты/фильтра/сокращения со стандартным J2SE. Извините, это на французском, но с переводом google вы можете прочитать: http://caron-yann.developpez.com/tutoriels/java/fonction-object-design-pattern-attendant-closures-java-8/
Вы можете использовать, если:
int sum = dogs.filter(new Predicate<Arguments2<Dog, Integer>>() {
@Override
public Boolean invoke(Arguments2<Dog, Integer> arguments) {
// filter on male
return arguments.getArgument1().getGender() == Dog.Gender.MALE;
}
}).<Integer>map(new Function<Integer, Arguments2<Dog, Integer>>() {
@Override
public Integer invoke(Arguments2<Dog, Integer> arguments) {
// get ages
return arguments.getArgument1().getAge();
}
}).reduce(new Function<Integer, Arguments2<Integer, Integer>>() {
@Override
public Integer invoke(Arguments2<Integer, Integer> arguments) {
// sum âges
return arguments.getArgument1() + arguments.getArgument2();
}
});
System.out.println("Le cumul de l'âge des mâles est de : " + sum + " ans");
Наслаждайтесь этой помощью