158

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

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

4

6 回答 6

106

从 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()

于 2014-01-08T15:05:01.093 回答
90

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

Guava虽然有一个Function接口,但该 方法提供了您需要的功能。
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);
于 2010-10-11T15:05:16.643 回答
26

有一个很棒的库,叫做Functional Java,它可以处理许多你希望 Java 拥有但它没有的东西。再说一次,还有一种很棒的语言 Scala,它做了 Java 应该做的所有事情,但仍然与为 JVM 编写的任何东西兼容。

于 2010-10-11T15:04:57.177 回答
9

使用番石榴要非常小心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 出现 lambdas 时,这当然会过时。

于 2013-05-31T10:18:50.220 回答
2

这是您可以使用地图的另一个功能库:http ://code.google.com/p/totallylazy/

sequence(1, 2).map(toString); // lazily returns "1", "2"
于 2012-12-04T11:32:34.633 回答
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);
于 2018-10-17T19:06:34.723 回答