Java:有地图功能吗?

Java:有地图功能吗?,java,map-function,Java,Map Function,我需要一个函数。Java中已经有类似的东西了吗 (对于那些想知道:我当然知道如何自己实现这个简单的函数…有一个很棒的库,名为,它可以处理许多您希望Java拥有的东西,但它没有。此外,还有一种很棒的语言Scala,它完成了Java应该做的一切,但却没有做到,同时仍然与为JVM编写的任何东西兼容。从Java 6开始,JDK中没有函数的概念 虽然有一个接口,但是 方法提供所需的功能 示例: // example, converts a collection of integers to their

我需要一个函数。Java中已经有类似的东西了吗


(对于那些想知道:我当然知道如何自己实现这个简单的函数…

有一个很棒的库,名为,它可以处理许多您希望Java拥有的东西,但它没有。此外,还有一种很棒的语言Scala,它完成了Java应该做的一切,但却没有做到,同时仍然与为JVM编写的任何东西兼容。

从Java 6开始,JDK中没有函数的概念

虽然有一个接口,但是
方法提供所需的功能

示例:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);
[a, 14, 1e, 28, 32]

现在,Java 8实际上有一个映射函数,所以我可能会用更简洁的方式编写代码:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);
Collection hex=input.stream()
.map(整数::toHexString)
.collect(收集器::toList);

这是另一个功能库,您可以使用它来映射:


小心使用番石榴的
Collections2.transform()
。 这种方法最大的优点也是最大的危险:懒惰

查看
Lists.transform()
的文档,我相信这也适用于
Collections2.transform()

该函数是惰性应用的,在需要时调用。这是必要的 返回的列表是一个视图,但这意味着函数 将多次应用于批量操作,如 List.contains(java.lang.Object)和List.hashCode()。为了这个 性能良好,功能应快速。避免在执行时进行惰性评估 返回的列表不需要是视图,复制返回的列表 进入您选择的新列表

同样在
Collections2.transform()
的文档中,他们提到您可以获得实时视图,源列表中的更改会影响转换后的列表。如果开发人员没有意识到它的工作方式,这种行为会导致难以跟踪的问题

如果你想要一个更经典的“地图”,它会一次又一次地运行,那么你最好还是使用番石榴,它的操作要简单得多。以下是谷歌的例子:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();
transform()
以下是映射方法。它使用与
Collections.transform()相同的函数“callbacks”。但是,返回的列表是只读的,请使用
copyInto()
获取读写列表


否则,当java8与lambdas一起推出时,这将是过时的。

由于java8,JDK中有一些标准选项可以实现这一点:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());
中的集合=。。。
Object[]mapped=in.stream().map(e->doMap(e)).toArray();
//或
List mapped=in.stream().map(e->doMap(e)).collect(Collectors.toList());

请参见和。

尽管这是一个老问题,但我想展示另一个解决方案:

只需使用java泛型和java 8流定义您自己的操作:

public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
   return collection.stream().map(mapFunction).collect(Collectors.toList());
}
公共静态列表映射(集合集合,函数映射函数){
返回collection.stream().map(mapFunction.collect(Collectors.toList());
}
您可以编写如下代码:

List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
List hex=map(Arrays.asList(10,20,30,40,50),Integer::toHexString);


在@Chris重复(相当好):怎么会是同一个问题?不是同一个问题。这是密切相关的…如果这个问题的答案是肯定的,它也回答了另一个相关的问题。如果答案是否定的(似乎是否定的),那么它们是完全不相关的他们扩展了编译器吗?还是添加了预处理器?@Andrey-你可以自己问他们,也可以查看源代码,看看是如何完成的。这里有一个到源代码的链接:@Andrey:examples使用BGGA闭包建议中的语法。虽然有正在运行的原型,但它还没有在“官方”Java中出现。@Andrey:这种语法是Java中闭包规范的一部分(见主页上倒数第二段)。只有一个原型实现。Scala线程劫持:(我希望它不会像JavaPosse邮件列表一样;)值得注意的是,虽然使用Guava可以做到这一点,但您可能不想:(阅读“注意事项”部分)。@AdamParkin是真的,但我很确定这指的是比这更高级的功能概念,否则他们就不会首先开发transform()方法事实上,不,函数式习惯用法通常会对性能造成一定的影响,这就是为什么他们强调,只有在您确定这些工具满足概述的两个标准时,才应该使用它们:从整体上讲,代码库的LOC净节省,以及由于延迟评估(或至少不是性能命中)而获得的经验证的性能增益。不是反对使用它们,只是表明如果你要这样做,你应该注意实现者的警告。@SeanPatrickFloyd现在Java 8已经过时了,想用一个涉及lambdas的例子来更新这个吗?像Java 8中的Daniel一样,我不认为有理由用番石榴来做这件事。相反,我会选择leventov的答案。这里有一个关于如何使用TotalyLazy的指南:这太冗长了,让我内心很难受。@Natix同意
toList()
。替换为不同的类型:
(List)((List)List.replaceAll(o->doMap((E)o));
可以用
E->doMap(E)
替换为
doMap
?@jameshfisher,是的,类似于
foo::doMap
foo::doMap
。我想这就是Scala存在的原因。等待Java12有可读的东西。
List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);