Java:有地图功能吗?

时间:2010-10-11 15:00:23

标签: java map-function

我需要一个map功能。 Java中是否有这样的东西?

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

6 个答案:

答案 0 :(得分:88)

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

答案 1 :(得分:84)

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

Guava虽然有Function界面,但是 Collections2.transform(Collection<E>, Function<E,E2>)
method提供了您需要的功能。

示例:

// 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);

答案 2 :(得分:25)

有一个名为Functional Java的精彩库,可以处理许多你想要Java拥有的东西,但事实并非如此。再说一次,还有一种非常好的语言Scala,可以完成Java应该完成的所有工作但不会与为JVM编写的任何内容兼容。

答案 3 :(得分: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()这是map方法。它使用相同的函数&lt;&gt; “回调”为Collections.transform()。您获取的列表是只读的,使用copyInto()来获取读写列表。

当然,当java8与lambdas一起出现时,这将是过时的。

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

即使是一个老问题,我也想展示另一个解决方案:

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

$reader = new Reader('GeoLite2-City.mmdb');
        $record  = $reader->city($ip);
       // $ip = $_SERVER['REMOTE_ADDR'];
        $iso_code = $record->country->isoCode;
        $timezone = $record->location->timeZone;

比您可以编写如下代码:

public static <S, T> List<T> mapAll(Collection<S> collection, Function<S, T> mapper) {
   return collection.stream().map(mapper).collect(Collectors.toList());
}