1.收集元素

最后,我们到达了类中最有趣的方法Streamcollect()方法。它用于从流移动到我们熟悉的集合—— List<T>Set<T>Map<T, R>其他。

collect()方法将一个特殊collector对象作为参数。该对象从流中读取所有数据,将其转换为特定类型的集合,然后返回。然后 collect 方法本身返回这个集合。

所有这些都是以一种相当巧妙的方式完成的:collector对象的类型是Collector<T, A, R>. 如您所见,它具有三个类型参数。最后一个类型参数 ( R) 通常是类似List<T>. 这意味着编译器可以使用此类型来确定方法本身的正确返回类型collect()

我希望你不要太困惑。在任何情况下,您都不需要自己创建 Collector 对象。类的静态方法返回的现成对象Collectors就足够了。

收藏

该类Collectors有几个静态方法可以返回现成的收集器对象——适合各种场合。在这里,我们将考虑最重要的。

toList()
将流转换为列表的对象 ( List<T>)
toSet()
将流转换为集合的对象 ( Set<T>)
toMap()
Map<K, V>将流转换为 map( )的对象
joining()
将流的元素连接成单个字符串
mapping()
将字符串的元素转换为Map<K, V>
groupingBy()
对元素进行分组并返回Map<K, V>

2. 将流转换为列表

以下是使用流并将结果转换为列表的典型示例

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

我们从集合中得到了一个流。然后我们通过只保留第一个字符是大写的字符串得到一个新的流。然后将该流中的所有数据收集到一个集合中,然后将其返回。



3. 将流转换为集合

以下是使用流并将结果转换为集合的典型示例

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

一切都与将流转换为 a 的代码非常相似List,只是我们使用了不同的收集器对象,该对象由该toSet()方法返回。



4. 将流转换为地图

但是将流转换为地图有点困难。Map 中的每个条目都包含两个元素:一个键和一个值。我们需要弄清楚我们将如何为流中的每个元素定义键和值。

例子:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

让我们来看看这里发生了什么。

在第一行中,我们使用map(...)将每个字符串转换为字符串数组。使用 split 方法,我们将每个字符串分成两部分。

在第二行中,我们filter()只将那些恰好包含两个元素的数组传递给该方法。该d==3字符串被拆分为三个元素的数组,这与过滤器不匹配。

最后,在最后一行中,我们将流转换为Map<String, String>. 两个函数被传递给该toMap()方法。对于流中的每个元素,第一个函数应该返回 key第二个函数返回 value

每个数组的第一个元素(“a”、“b”、“c”)将是我们的键,每个数组的第二个元素(“2”、“3”、“4”)将是我们的值。



5. 将流转换为字符串

另一个有趣的收集器对象由 返回Collectors.joining()。它将流的所有元素转换为String并将它们连接成一个字符串。例子

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );