Java:有没有地图function?
我需要一个地图function。 Java中是否有这样的东西?
(对于那些想知道:我当然知道如何实现这个微不足道的function…)
JDK中没有Java 6中的函数概念。
番石榴有一个function界面,虽然和
Collections2.transform(Collection<E>, Function<E,E2>)
方法提供了您需要的function。
例:
// 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中,实际上有一个map函数,所以我可能会以更简洁的方式编写代码:
Collection<String> hex = input.stream() .map(Integer::toHexString) .collect(Collectors::toList);
从Java 8开始,在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()
。
有一个叫做Functional Java的很棒的库,它处理了许多你想要Java的东西,但事实并非如此。 再说一遍,这里还有一些Scala语言,它完成了Java应该完成的所有工作,但是仍然与为JVM编写的任何东西兼容。
用Guava中的Collections2.transform()
非常小心。 那个方法最大的好处也是它最大的危险:懒惰。
看看Lists.transform()
的文档,我相信这也适用于Collections2.transform()
:
该function被懒惰地应用,需要时被调用。 这对于返回的列表是一个视图是必要的,但是这意味着这个函数将被多次应用于像List.contains(java.lang.Object)和List.hashCode()这样的批量操作。 为了performance良好,function应该很快。 当返回列表不需要是视图时,为了避免延迟评估,请将返回的列表复制到您select的新列表中。
同样在Collections2.transform()
的文档中,他们提到您会得到一个实时视图,源列表中的更改会影响转换后的列表。 如果开发人员没有意识到这种行为的方式,这种行为会导致难以跟踪的问题。
如果你想要一个更经典的“地图”,那将只运行一次,那么你最好用FluentIterable
,也从Guava,它有一个更简单的操作。 这是谷歌的例子:
FluentIterable .from(database.getClientList()) .filter(activeInLastMonth()) .transform(Functions.toStringFunction()) .limit(10) .toList();
transform()
这里是map方法。 它使用与Collections.transform()
相同的Function <>“callback”。 你得到的列表是只读的,使用copyInto()
来获得一个读写列表。
否则,当java8出来lambdas,这将是过时的。
这是另一个可以使用map的function库: http : //code.google.com/p/totallylazy/
sequence(1, 2).map(toString); // lazily returns "1", "2"