有地图功能吗?

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

(对于那些想知道: 我当然知道如何自己实现这个微不足道的函数...)

161773 次浏览

有一个叫做 函数式 Java的很棒的库,它可以处理很多你希望 Java 拥有的东西,但是它没有。然后,还有这个奇妙的语言 Scala,它做了 Java 应该做的所有事情,但是没有做,同时仍然与为 JVM 编写的任何东西兼容。

在 java 6中,JDK 中没有函数的概念。

但是,Guava 有一个 功能接口,并且
Collections2.transform(Collection<E>, Function<E,E2>)
方法提供您需要的功能。

例如:

// 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]

现在,在 Java8中,实际上有一个 map 函数,所以我可能会用一种更简洁的方式来编写代码:

Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);

这是另一个可以使用 map 的函数库: http://code.google.com/p/totallylazy/

sequence(1, 2).map(toString); // lazily returns "1", "2"

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

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

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

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

如果你想要一个更经典的“ map”,它只能运行一次,那么你最好使用 FluentIterable,也是来自 Guava,它有一个更简单的操作。下面是谷歌的例子:

FluentIterable
.from(database.getClientList())
.filter(activeInLastMonth())
.transform(Functions.toStringFunction())
.limit(10)
.toList();

这里的 transform()是映射方法。它使用与 Collections.transform()相同的函数 < > “ callback”。但是返回的列表是只读的,可以使用 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());

参见 java.util.Collection.stream()java.util.stream.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());
}

然后你就可以编写这样的代码:

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