我需要一个地图功能。Java中已经有类似的东西了吗?
(对于那些想知道的人:我当然知道如何自己实现这个琐碎的功能...)
我需要一个地图功能。Java中已经有类似的东西了吗?
(对于那些想知道的人:我当然知道如何自己实现这个琐碎的功能...)
Answers:
从Java 6开始,JDK中没有函数的概念。
番石榴具有功能接口,但是该
方法提供了您所需的功能。
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]
如今,在Java 8中,实际上已经有了一个map函数,因此我可能会以一种更为简洁的方式编写代码:
Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);
Collections2.transform(input -> Integer.toHexString(intput.intValue())
从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()
。
toList()
。替换为其他类型:(List<R>)((List) list).replaceAll(o -> doMap((E) o));
e -> doMap(e)
用替换doMap
吗?
foo::doMap
或Foo::doMap
。
有一个很棒的库,叫做Functional Java,可以处理您希望Java拥有但没有的许多东西。再说一遍,还有一种很棒的语言Scala,它可以执行Java应该做的所有事情,但仍然不能与为JVM编写的任何东西兼容。
a.map({int i => i + 42});
它们扩展了编译器吗?或添加了预处理器?
小心Collections2.transform()
来自番石榴。该方法的最大优点也是最大的危险:惰性。
查看的文档Lists.transform()
,我相信它也适用于Collections2.transform()
:
该函数延迟应用,在需要时调用。对于返回的列表来说,这是必需的,但是这意味着该函数将多次用于批量操作,如List.contains(java.lang.Object)和List.hashCode()。为使此功能正常运行,功能应该很快。为了避免在返回的列表不需要成为视图时进行延迟评估,请将返回的列表复制到您选择的新列表中。
同样在Collections2.transform()
他们提到的文档中,您可以获得实时视图,源列表中的更改会影响转换后的列表。如果开发人员不了解其工作方式,则这种行为可能导致难以跟踪的问题。
如果您想要一个更经典的“地图”,该地图只能运行一次,那么最好使用FluentIterable
Guava的,它的操作要简单得多。这是谷歌的例子:
FluentIterable
.from(database.getClientList())
.filter(activeInLastMonth())
.transform(Functions.toStringFunction())
.limit(10)
.toList();
transform()
这是地图方法。它使用与相同的Function <>“回调” Collections.transform()
。您返回的列表是只读的,但copyInto()
用于获取读写列表。
否则,当然当java8带有lambda时,这将是过时的。
这是您可以使用地图的另一个功能库:http : //code.google.com/p/totallylazy/
sequence(1, 2).map(toString); // lazily returns "1", "2"
即使这是一个古老的问题,我也想展示另一个解决方案:
只需使用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);