Я недавно представил вопрос , где я запросил / обсудил нечто подобное. Это то, что потребуется в моей реализации
/**
* 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();
Это определенно не то, о чем вы просите, но во многих случаях это будет проще, и оно будет совпадать с вашим запросом (даже если подход другой).