我正在寻找最轻松的方式来过滤集合。我在想类似的东西
Collection<?> foo = existingCollection.stream().filter( ... ). ...
但我不确定如何最好地从过滤器返回或填充另一个集合。大多数示例似乎就像“在这里您可以打印”。可能有我缺少的构造函数或输出方法。
我正在寻找最轻松的方式来过滤集合。我在想类似的东西
Collection<?> foo = existingCollection.stream().filter( ... ). ...
但我不确定如何最好地从过滤器返回或填充另一个集合。大多数示例似乎就像“在这里您可以打印”。可能有我缺少的构造函数或输出方法。
大多数示例避免将结果存储到Collection
. 这不是推荐的编程方式。您已经有一个Collection
,提供源数据和集合的那个本身没有用。您想对其执行某些操作,因此理想的情况是使用流执行操作并跳过将数据存储在中间Collection
. 这是大多数例子试图暗示的。
当然,有很多现有的 API 与Collection
s 一起使用,而且总会有。因此Stream
API 提供了不同的方法来处理对Collection
.
获取List
包含所有元素的不可修改的实现(JDK 16):
List<T> results = l.stream().filter(…).toList();
获取保存结果的任意List
实现:
List<T> results = l.stream().filter(…).collect(Collectors.toList());
获得一个不可修改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
)
java.util.stream
的文档中的一个示例:
List<String>results =
stream.filter(s -> pattern.matcher(s).matches())
.collect(Collectors.toList());
Collectors
有一个toCollection()
方法,我建议这样看。
作为一个更符合 Java 8 函数式编程风格的示例:
Collection<String> a = Collections.emptyList();
List<String> result = a.stream().
filter(s -> s.length() > 0).
collect(Collectors.toList());
您可能想要使用toList
或toSet
或类中的toMap
方法Collectors
。
但是,为了获得更多控制,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