由于 Java 对集合的函数式操作并非原生态的,必须对得到的 stream() 进行过滤等操作,之后还是一个 stream(),一般我们最后返回给调用者需还原为相应的集合。这无法与 Scala 的 for ... yield
操作相比。例如下面在使用 Stream API 过滤获得所有大于 3 的数字之后,方法的返回值还应该还原为 List<Integer>, 这个需求非常自然
1 2 3 4 5 |
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); List<Integer> greaterThan3(list) { Stream<Integer> streamOfInteger = list.stream().filter( i -> i > 3); return streamOfInteger.ToIntegerList......; } |
我们这儿的问题就是如何把上面的 streamOfInteger 转换为 List<Integer>, 有以下几种办法
1 使用 Collectors.toList 方法 ***
1 |
streamOfInteger.collect(Collectors.toList()); |
2 使用 toCollection() 方法 **
1 |
streamOfInteger.collect(Collectors.toCollection(ArrayList::new)) |
3 forEach() 方法 *
1 2 3 |
List<Integer> newList = new ArrayList<>(); streamOfInteger.forEach(newList::add); streamOfInteger.forEachOrdered(newList::add); //或者 |
需要借助于临时变量,不带为 Functional 接受
4. toArray() 方法
1 2 |
Integer[] arrayOfInteger = streamOfInteger.toArray(Integer[]::new); List<Integer> newList = Arrays.asList(arrayOfInteger); |
此法更觉多此一举
此外,不妨窥探下使用 Stream API 处理后的 Map 该如何还原为 Map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Map<String, String> map = new HashMap<>(); map.put("a", "aa"); map.put("b", "bb"); Stream<Map.Entry<String, String>> filtered = map.entrySet().stream() .filter(entry -> entry.getKey().equals("b")); filtered.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); //或 filtered.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())); //或 Map<String, String> newMap = new HashMap<>(); filtered.forEach(entry -> newMap.put(entry.getKey(), entry.getValue())); |
如果我们根本用不着对原有的 key/value 作进一步加工处理,只是应用原始的 key/value 生成新的 Map,那么我们可以自定义一个通用的 Collector. 这是功课,且到用时再思考。
参考: 1. 5 ways to Convert Java 8 Stream to List - Example, Tutorial
本文链接 https://yanbin.blog/java-8-stream-to-collection/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。