【问题标题】:How can I write a higher order function like map, or reduce in java?如何在 java 中编写 map 或 reduce 之类的高阶函数?
【发布时间】:2011-04-26 06:51:14
【问题描述】:

我在 Joel On Software 上阅读了一篇关于使用高阶函数通过使用 map 和 reduce 大大简化代码的想法的文章。他提到这在 Java 中很难做到。文章:http://www.joelonsoftware.com/items/2006/08/01.html

下面文章中的示例循环遍历一个数组,并使用作为参数传递给数组中每个元素的函数 fn:

function map(fn, a)
{
    for (i = 0; i < a.length; i++)
    {
        a[i] = fn(a[i]);
    }
}

这将在实践中类似于以下调用:

map( function(x){return x*2;}, a );
map( alert, a );

如果可能的话,我想写一个映射函数来处理数组或任何类型的集合。

我一直在 Internet 上四处寻找,但很难找到有关该主题的资源。首先,java中可以使用匿名函数吗?这有可能以另一种方式做到吗?它会在 Java 的未来版本中提供吗?如果可能,我该怎么做?

我想如果这在 Java 中是不可能的,那么人们可以使用某种“模式”/技术来实现相同的效果,因为我认为匿名函数是软件世界中非常强大的工具。我能找到的唯一类似问题是:Java generics - implementing higher order functions like map,这对我来说完全没有意义。

【问题讨论】:

    标签: java functional-programming higher-order-functions


    【解决方案1】:

    Guava 提供地图(但它被称为transform,并且在ListsCollections2 等实用程序类中)。但是,它不提供折叠/减少。

    无论如何,与在 Scheme 中使用 map 相比,使用 transform 的语法感觉非常笨拙。这有点像用左手写字,如果你是右手的话。但是,这是 Java;你能指望什么。 :-P

    【讨论】:

      【解决方案2】:

      看起来像这个?

      How can I write an anonymous function in Java?

      P.S:试试Functional Java。也许它可以给你提示。

      【讨论】:

        【解决方案3】:

        单方法匿名类提供了一种类似但更冗长的 Java 编写匿名函数的方式。 例如,您可以:

        Iterable<Source> foos = ...;
        Iterable<Destination> mappedFoos = foos.map(new Function<Source, Destination>() 
        {
            public Destination apply(Source item) { return ... }
        });
        

        有关函数式风格的 Java 库示例,请参阅Guava

        【讨论】:

        • 确实,如果/当 Java 最终获得 lambda 表达式时,它们似乎可以转换为这样的匿名类。
        【解决方案4】:
        interface Func<V,A> {
            V call (A a);
        }
        
        static <V,A> List<V> map (Func<V,A> func, List<A> as) {
            List<V> vs = new ArrayList<V>(as.size());
            for (A a : as) {
                Vs.add(func.call(a));
            }
            return vs;
        }
        

        【讨论】:

          【解决方案5】:

          Paguro has an open-source implementation of higher order functions。初始测试表明它比原生 Java forEach 循环快 98%。它支持的操作是懒惰地应用而不修改底层集合。它输出到不可变(有时是可变)Clojure 集合的类型安全版本。 Transformable is built into Paguro's unmodifiable and immutable collections and interfaces。要使用原始 java.util 集合作为输入,只需将其包装为 xform() 函数即可。

          【讨论】:

            最近更新 更多