Java:有地图功能吗?

Alb*_*ert 135 java map-function

我需要一个地图功能.Java中有这样的东西吗?

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

lev*_*tov 90

从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());
Run Code Online (Sandbox Code Playgroud)

java.util.Collection.stream()java.util.stream.Collectors.toList().

  • 这非常冗长,让我内心受伤. (132认同)
  • 我想这就是Scala存在的原因.等待Java 12具有可读性. (9认同)
  • @jameshfisher,是的,像`foo :: doMap`或`Foo :: doMap`. (3认同)
  • 可以`e - > doMap(e)`只用'doMap`替换? (2认同)

Sea*_*oyd 86

从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);
Run Code Online (Sandbox Code Playgroud)

输出:

[a, 14, 1e, 28, 32]
Run Code Online (Sandbox Code Playgroud)

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

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,虽然使用Guava你可以*做到这一点,你可能不想:http://code.google.com/p/guava-libraries/wiki/FunctionalExplained(阅读"注意事项"部分). (8认同)
  • @SeanPatrickFloyd现在Java 8已经出来了,想用一个涉及lambdas的例子更新这个吗?像`Collections2.transform(input - > Integer.toHexString(intput.intValue())` (3认同)
  • @AdamParkin是的,但我很确定这是指比这更高级的功能概念,否则他们不会首先开发*transform(*)方法 (2认同)
  • 实际上,不,通常会有功能习惯性的明显性能,这就是为什么他们强调你应该只使用这些设施,如果你确定它符合所列出的两个标准:整个代码库的净节约,以及*由于懒惰评估(或至少没有性能命中)而证明*性能提升.不反对使用它们,只是说明如果你要去,你应该留意实施者的警告. (2认同)
  • @Daniel 在 Java 8 中,我认为没有理由使用 Guava 来做到这一点。相反,我会去寻求列文托夫的回答 (2认同)

whe*_*ies 26

有一个很棒的库叫做Functional Java,可以处理你想要Java拥有的许多东西,但事实并非如此.然后,还有这个美妙的语言Scala,它可以完成Java应该完成的所有工作但不会与为JVM编写的任何内容兼容.

  • Scala线程劫持:(我希望SO不会像JavaPosse邮件列表那样;) (2认同)

Emm*_*ery 9

Collections2.transform()来自番石榴非常小心.这种方法的最大优点也是它最大的危险:它的懒惰.

请查看Lists.transform()我认为适用的文档Collections2.transform():

该函数被懒惰地应用,在需要时调用.这对于返回的列表是一个视图是必要的,但这意味着该函数将多次应用于List.contains(java.lang.Object)和List.hashCode()等批量操作.为了表现良好,功能应该很快.要在返回的列表不需要是视图时避免延迟评估,请将返回的列表复制到您选择的新列表中.

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

如果你想要一个更经典的"地图",将运行一次,并且只有一次,那么你有更好FluentIterable,也从番石榴,具有操作这是更简单.这是谷歌的例子:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();
Run Code Online (Sandbox Code Playgroud)

transform()这是地图方法.它使用相同的Function <>"callbacks"作为Collections.transform().您获取的列表是只读的,用于copyInto()获取读写列表.

当然,当java8出现lambda时,这将是过时的.