java 番石榴是否有等价于 Python 的 reduce 函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5023743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:06:19  来源:igfitidea点击:

Does guava have an equivalent to Python's reduce function?

javaguavafunctional-programming

提问by benhsu

Does guava (or another java library) have something like reduce() function in Python?

番石榴(或其他 Java 库)在 Python 中有类似 reduce() 函数的功能吗?

I'm looking for something like this http://docs.python.org/library/functions.html#reduce

我正在寻找这样的东西http://docs.python.org/library/functions.html#reduce

采纳答案by Stephen C

I've not (yet) managed to find any Java collections libraries that support mapand reduce. (I exclude map/reduce functionality in parallel / distributed processing frameworks ... because you need a "big" problem for these frameworks to be worthwhile.)

我还没有(还)设法找到任何支持mapreduce. (我排除了并行/分布式处理框架中的 map/reduce 功能......因为这些框架需要一个“大”问题才值得。)

Probably, the reason for this "lack" is that map/reduce coding without closures is just too cumbersome. Too much boilerplate code, too much heavy-weight syntax. Since the main point of using map / reduce primitives on simple collections is to make your code simple and elegant ...

可能这种“缺乏”的原因是没有闭包的 map/reduce 编码太麻烦了。太多的样板代码,太多的重量级语法。由于在简单集合上使用 map/reduce 原语的主要目的是使您的代码简单而优雅......



@CurtainDog contributed a link to lambdaj. That does the kind of thing that the OP is after (though there's no method specifically called reduce). But it illustrates what I was saying about boilerplate. Notice that many of the higher order operations involve creating classes that extend one or other of the Closureclasses.

@CurtainDog 提供了一个指向lambdaj的链接。这就是 OP 所追求的(尽管没有专门调用的方法reduce)。但它说明了我所说的关于样板的内容。请注意,许多高阶操作涉及创建扩展一个或其他Closure类的类。

(FWIW, I think that the Lambda.aggregate(...)methods are the lambdaj analog of reduce.)

(FWIW,我认为这些Lambda.aggregate(...)方法是 lambdaj 的类似物reduce。)

回答by ColinD

No. It might eventually, though functional stuff like that isn't a core focus of Guava. See this issue.

不。它最终可能会,尽管像这样的功能性东西不是 Guava 的核心焦点。看到这个问题

回答by Noam Samuel

Java 8 streams allow you to do this.

Java 8 流允许您执行此操作。

mylist.stream().map((x) -> x + 1).reduce((a,b) -> a + b)

For more information: http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

有关更多信息:http: //docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

回答by Sean Patrick Floyd

I have recently submitted an issuewhere I requested / discussed something similar. This is what would be needed in my implementation

我最近提交了一个问题,我要求/讨论了类似的问题。这是我的实现中所需要的

/**
 * 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)
    );
}

(The selector function can pull the value to aggregate from the object to query, but in many cases it will be Functions.identity(), i.e. the object itself is what's aggregated)

(选择器函数可以从对象中提取要聚合的值进行查询,但在很多情况下它会是Functions.identity(),即对象本身就是聚合的内容)

This is not a classic fold, but it requires a Function<Iterable<X>,X>to do the work. But since the actual code is a one-liner, I have instead chosen to request some standard aggregator functions (I'd put them in a class called something like Aggregators, AggregatorFunctionsor even Functions.Aggregators):

这不是一个经典的折叠,但它需要一个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()

(You can see my sample implementations in the issue)

(您可以在问题中看到我的示例实现)

That way, you can do things like this:

这样,您可以执行以下操作:

int[] numbers = { 1, 5, 6, 9, 11111, 54764576, 425623 };
int sum = Aggregators.sumOfIntegers().apply(Ints.asList(numbers)).intValue();

This is definitely not what you are asking for, but it would make like easier in many cases and would overlap with your request (even if the approach is different).

这绝对不是您所要求的,但在许多情况下它会更容易并且会与您的请求重叠(即使方法不同)。

回答by Channing Walton

Jedi has a reduceoperation. Jedi also helps reduce the boiler plate by using annotations to generate functors for you. See these examples.

Jedi有一个reduce操作。Jedi 还通过使用注释为您生成函子来帮助减少样板。请参阅这些示例

回答by Lars Bohl

Guava has transform(map). Seems like reduce is missing though?

番石榴有变换(贴图)。好像还没有减少?

回答by Wojtek B.

Use Totally Lazy, it implements all of those things an even more. It basicly copied the whole funcional approach from Clojure.

使用Totally Lazy,它甚至更多地实现了所有这些东西。它基本上复制了Clojure的整个功能方法。

回答by user81295

I have developed a library to do map/filter/reduce with standard J2SE. Sorry it is in french, but with google translate you can read it : http://caron-yann.developpez.com/tutoriels/java/fonction-object-design-pattern-attendant-closures-java-8/

我开发了一个库来使用标准 J2SE 进行映射/过滤/减少。对不起,它是法语,但用谷歌翻译你可以阅读它:http: //caron-yann.developpez.com/tutoriels/java/fonction-object-design-pattern-attendant-closures-java-8/

You can use if like this :

你可以这样使用:

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 ages
        return arguments.getArgument1() + arguments.getArgument2();
    }
});

System.out.println("Le cumul de l'age des males est de : " + sum + " ans");

Enjoy this help

享受这个帮助