我最近在submitted an issue 请求/讨论过类似的事情。这就是我的实现所需要的
/**
* 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();
这绝对不是您所要求的,但在许多情况下它会更容易,并且会与您的请求重叠(即使方法不同)。