【问题标题】:Distinct items List, Set, HashSet, Lambda, Java 8不同的项目 List、Set、HashSet、Lambda、Java 8
【发布时间】:2019-10-02 02:09:31
【问题描述】:

为了在List中获得不同项,我有三种选择

return new ArrayList<>(new HashSet<>(someTypeList));

return new HashSet<>(someTypeList).stream().collect(Collectors.toList());

return someTypeList.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());

您向我推荐什么选项以及为什么?

如果存在一些单一的替代方案,请告诉我。

【问题讨论】:

  • 最好将流作为someTypeList.stream().distinct().collect(Collectors.toList()) 并且没有它作为您的声明的第一个。但答案可能只是基于这些问题的意见。
  • IMO,我会去的。 someTypeList.stream().distinct().collect(Collectors.toList())

标签: list arraylist java-8 set hashset


【解决方案1】:

你应该保持一致,而不是混合不同的方法。

Collection API 方法使用任一

  • new ArrayList&lt;&gt;(new HashSet&lt;&gt;(someTypeList))
  • new ArrayList&lt;&gt;(new LinkedHashSet&lt;&gt;(someTypeList))当您想保留订单时

然后是 Stream API 方法

  • someTypeList.stream().distinct().collect(Collectors.toList());
  • someTypeList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
    当您需要结果恰好是 ArrayList

someTypeList 是一个普通的List 实现时,Collection 方法不仅更简单,而且效率更高。无论如何,Stream API 在内部使用HashSet,在实现distinct() 时,但collect 操作会受到抽象的影响,因为它没有关于预期元素数量的提示。相比之下,ArrayList 构造函数将简单地在传入的HashSet 上调用toArray 并将结果用作其支持数组。

someTypeList 是未知集合时,情况会发生变化。在某些场景下,Stream API 可能会利用源的特性来优化操作。如果源已经有不同的元素,比如Set,则distinct() 的开销将被消除。如果源已排序,将使用不同的算法来识别重复项,不需要HashSet

由于 Stream API 封装了实际的实现,它可能会在未来得到改进,而无需调整客户端代码。相比之下,显式 Collection 操作将始终完全按照其被告知的方式执行操作,而不会从其他实施策略中受益。

【讨论】:

    【解决方案2】:
    • 第一个选项 不保留列表的原始顺序,还必须构造集合然后复制到列表。
    • 第一个选项比第二个更好,因为流会影响性能。
    • 优于第​​三个选项someTypeList.stream().distinct().collect(Collectors.toList())

    因此,如果订购不是问题,那么第一个选项会更好。 还有一些第三方库提供了更好的性能

    例如Guava ImmutableSet

    ImmutableSet.copyOf(listInts).asList();

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      相关资源
      最近更新 更多