【问题标题】:Is this correct usage of lambdas in Java 8?这是 Java 8 中 lambda 的正确用法吗?
【发布时间】:2015-04-14 21:07:32
【问题描述】:
final List<String> userIds = request.getUserIds();
final List<String> keys = userIds.stream().map(p -> { 
    return removePrefix(p); 
}).collect(Collectors.toList());

基本上,userIds 列表中的每个键都包含一个前缀“_user”,我想为每个键删除它。所以,我在列表的每个项目上调用removePrefix 函数并将结果存储在另一个名为“keys”的列表中

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    是的,虽然您可以使用方法引用和静态导入使其更短且更具可读性:

    final List<String> keys = userIds.stream()
                                     .map(this::removePrefix)
                                     .collect(toList());
    

    【讨论】:

    • .map(p -&gt; removePrefix(p)).map(this::removePrefix) 有什么区别。是的,第一个更长,有 2 个字符,但还有什么?
    • 没有功能差异 - 但我发现方法参考更具可读性。这显然是一个品味问题......
    • @NagyVilmos 这很容易被验证...这里有更多关于这个主题的信息:stackoverflow.com/questions/24487805/…
    • @Nagy Vilmos:不,它们略有不同。方法引用不需要合成方法来保存 lambda 的代码,而是直接引用目标方法。好吧,在大多数情况下;有时它需要一个与 lambda 表达式完全相同的辅助方法,例如用于可变参数方法或数组构造函数。
    【解决方案2】:

    @assylias 的答案很好,但如果您不担心修改列表(并且允许您通过其 ListIterator#set 方法修改它),一个不错的选择可能是使用 replaceAll

    final List<String> userIds = request.getUserIds();
    userIds.replaceAll(this::removePrefix);
    

    replaceAll 在这里工作,因为您的函数是从 T 到 T 的函数(在您的情况下,T 是 String),所以基本上是 UnaryOperator,即 Function&lt;T,T&gt;

    如果您要应用的映射是从类型 T 到 U,那么获取列表的流并通过 Stream#map 方法进行映射(就像您所做的那样)是标准习惯用法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 2014-02-11
      • 2019-04-07
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多