【问题标题】:Java: is there a map function?Java:有地图功能吗?
【发布时间】:2019-12-02 15:02:11
【问题描述】:

我需要一个map 函数。 Java中已经有类似的东西了吗?

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

【问题讨论】:

  • @Chris:怎么是同一个问题?
  • 这不是同一个问题。虽然它密切相关......
  • 如果这个问题的答案是肯定的,它也会回答另一个链接的问题。如果答案是否定的(看起来确实如此),那么它们是完全不相关的。
  • 从 Java8 开始,这可能是 @delnan 所指的 leveluplunch.com/java/examples/…

标签: java map-function


【解决方案1】:

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

【讨论】:

  • 这太冗长了,我内心很痛苦。
  • @Natix 同意toList()。替换为不同类型:(List&lt;R&gt;)((List) list).replaceAll(o -&gt; doMap((E) o));
  • 可以将e -&gt; doMap(e) 替换为doMap 吗?
  • @jameshfisher,是的,类似于foo::doMapFoo::doMap
  • 我想这就是 Scala 存在的原因。等待 Java 12 具有可读性。
【解决方案2】:

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

Guava 有一个Function 接口,而
Collections2.transform(Collection&lt;E&gt;, Function&lt;E,E2&gt;)
方法提供您需要的功能。

示例:

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

【讨论】:

  • 值得注意的是,虽然使用 Guava 您可以做到这一点,但您可能不想这样做:code.google.com/p/guava-libraries/wiki/FunctionalExplained(阅读“注意事项”部分)。
  • @AdamParkin 是的,但我很确定这指的是比这更高级的功能概念,否则他们不会一开始就开发出 transform() 方法地点
  • 实际上,不,函数式惯用语通常会对性能造成一定的影响,这就是为什么他们强调只有在您确定它符合列出的两个标准时才应该使用这些设施:LOC 的净节省代码库作为一个整体,以及由于延迟评估(或至少不是性能命中)而经过验证的性能提升。不反对使用它们,只是表明如果你打算这样做,你应该注意实施者的警告。
  • @SeanPatrickFloyd 现在 Java 8 已经发布,想用一个涉及 lambdas 的例子来更新它吗?喜欢Collections2.transform(input -&gt; Integer.toHexString(intput.intValue())
  • @Daniel 在 Java 8 中,我认为没有理由使用 Guava。相反,我会去寻求 leventov 的答案
【解决方案3】:

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

【讨论】:

  • 我对他们如何启用以下语法感兴趣:a.map({int i =&gt; i + 42}); 他们是否扩展了编译器?还是添加了预处理器?
  • @Andrey - 您可以自己询问他们,也可以查看源代码以了解它是如何完成的。以下是源链接:functionaljava.org/source
  • @Andrey:示例使用 BGGA 闭包提案中的语法。虽然有正在运行的原型,但它还不是“官方”Java。
  • @Andrey:该语法是 Java 闭包提议规范的一部分(参见主页倒数第二段)。只有一个原型实现。
  • Scala 线程劫持 :( 我希望 SO 不会像 JavaPosse 邮件列表那样;)
【解决方案4】:

小心使用来自番石榴的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方法。它使用与Collections.transform() 相同的函数“回调”。您返回的列表是只读的,但请使用copyInto() 获取读写列表。

当然,当 java8 推出 lambdas 时,这将被淘汰。

【讨论】:

    【解决方案5】:

    这是另一个可以使用 map 的函数库:http://code.google.com/p/totallylazy/

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

    【讨论】:

    【解决方案6】:

    尽管这是一个老问题,但我想展示另一种解决方案:

    只需使用 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 2011-06-14
      相关资源
      最近更新 更多