流式传输到新集合的集合

时间:2014-02-03 08:05:03

标签: java java-8 java-stream

我正在寻找最无痛的方式来过滤集合。我在想像

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

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

4 个答案:

答案 0 :(得分:109)

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

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

  • 获取包含结果的任意List实现:

    List<T> results = l.stream().filter(…).collect(Collectors.toList());
    
  • 获取包含结果的任意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()收集器的未来实现仍将返回{{1 }})

答案 1 :(得分:4)

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

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

CollectorstoCollection()方法,我建议这样看。

答案 2 :(得分:3)

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

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

答案 3 :(得分:0)

您可能希望使用toList类中的toSettoMapCollectors方法。

但是,可以使用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