【问题标题】:Collection to stream to a new collection集合以流式传输到新集合
【发布时间】:2014-02-26 15:25:47
【问题描述】:

我正在寻找最轻松的方法来过滤集合。我在想类似的东西

Collection<?> foo = existingCollection.stream().filter( ... ). ...

但我不确定如何最好地从过滤器返回或填充另一个集合。大多数示例似乎就像“在这里您可以打印”。可能有我缺少的构造函数或输出方法。

【问题讨论】:

标签: java java-8 java-stream


【解决方案1】:

大多数示例避免将结果存储到Collection 中是有原因的。这不是推荐的编程方式。您已经有一个Collection,提供源数据和集合的那个本身没有用。您想对其执行某些操作,因此理想的情况是使用流执行操作并跳过将数据存储在中间Collection 中。这是大多数例子试图暗示的。

当然,有很多现有的 API 与 Collections 一起使用,而且总会有。因此Stream API 提供了不同的方式来处理对Collection 的需求。

  • 获取包含所有元素的不可修改的 List 实现 (JDK 16):

    List<T> results = l.stream().filter(…).toList();
    
  • 获取一个任意的List 实现来保存结果:

    List<T> results = l.stream().filter(…).collect(Collectors.toList());
    
  • 获取unmodifiable List 禁止null 喜欢List.of(…) (JDK 10):

    List<T> results = l.stream().filter(…).collect(Collectors.toUnmodifiableList());
    
  • 获取一个任意的Set 实现来保存结果:

    Set<T> results = l.stream().filter(…).collect(Collectors.toSet());
    
  • 获取特定的Collection

    ArrayList<T> results =
      l.stream().filter(…).collect(Collectors.toCollection(ArrayList::new));
    
  • 添加到现有的Collection

    l.stream().filter(…).forEach(existing::add);
    
  • 创建一个数组:

    String[] array=l.stream().filter(…).toArray(String[]::new);
    
  • 使用数组创建具有特定特定行为(可变、固定大小)的列表:

    List<String> al=Arrays.asList(l.stream().filter(…).toArray(String[]::new));
    
  • 允许并行能力的流添加到临时本地列表并在之后加入它们:

    List<T> results
      = l.stream().filter(…).collect(ArrayList::new, List::add, List::addAll);
    

    (注意:这与Collectors.toList() 当前的实现方式密切相关,但这是一个实现细节,即不能保证toList() 收集器的未来实现仍将返回ArrayList

【讨论】:

    【解决方案2】:

    您可能想要使用来自Collectors 类的toListtoSettoMap 方法。

    但是,要获得更多控制,可以使用toCollection 方法。这是一个简单的例子:

    Collection<String> c1 = new ArrayList<>();
    c1.add("aa");
    c1.add("ab");
    c1.add("ca");
    
    Collection<String> c2 = c1.stream().filter(s -> s.startsWith("a")).collect(Collectors.toCollection(ArrayList::new));
    
    Collection<String> c3 = c1.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
    
    c2.forEach(System.out::println); // prints-> aa ab
    c3.forEach(System.out::println); // prints-> aa ab
    

    【讨论】:

      【解决方案3】:

      来自java.util.stream 文档的示例:

      List<String>results =
           stream.filter(s -> pattern.matcher(s).matches())
                 .collect(Collectors.toList());
      

      Collectors 有一个toCollection() 方法,我建议这样看。

      【讨论】:

        【解决方案4】:

        作为一个更符合 Java 8 函数式编程风格的示例:

        Collection<String> a = Collections.emptyList();
        List<String> result = a.stream().
             filter(s -> s.length() > 0).
             collect(Collectors.toList());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-10-09
          • 1970-01-01
          • 1970-01-01
          • 2016-05-26
          • 1970-01-01
          相关资源
          最近更新 更多