尚学堂 老师好!

上海:15201841284

广州:020-2989 6995

深圳:0755-23061965

武汉:027-8798 9193

西安:029-8822 8155

别把所有问题都硬塞给 Java 8 Streams

随着Java8成为主流,人们开始在所有地方使用流api(Steams),甚至在那些有点生硬的情景下(也就是,夸张一点说,完全疯了).举个例子,看下面mykong的这篇展示如何将Map的entry set流转化为一个键的List和一个值的List的文章: https://www.mkyong.com/java8/java-8-convert-map-to-list

更多精彩内容以及学习资料,尚学堂论坛bbs.bjsxt.com免费下载。

发布在mykong.com上的代码分两个步骤来做这件事:

 package com.mkyong.example;  import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors;  public class ConvertMapToList {     public static void main(String[] args) {         Map map = new HashMap<>();         map.put(10, "apple");         map.put(20, "orange");         map.put(30, "banana");         map.put(40, "watermelon");         map.put(50, "dragonfruit");          System.out.println("/n1. Export Map Key to List...");          List result = map.entrySet().stream()                 .map(x -> x.getKey())                 .collect(Collectors.toList());          result.forEach(System.out::println);          System.out.println("/n2. Export Map Value to List...");          List result2 = map.entrySet().stream()                 .map(x -> x.getValue())                 .collect(Collectors.toList());          result2.forEach(System.out::println);     } } 

你自己的代码通常不应该这样做.首先,如果你不介意遍历map两次,那么最简单的聚集map的键和值的方式应该是下面这样的:

 List result1 = new ArrayList<>(map.keySet()); List result2 = new ArrayList<>(map.values()); 

在这个特定例子中绝对没有必要采用Java 8的streams.上面的代码实现显得既简洁又高效.

别把所有问题都塞给Java 8 Streams.

但是如果你真的想要使用streams,那么我个人倾向于在一行代码做这件事的解决方案.在这个特定的例子中没必要遍历Map两次.举例来说,你可以使用jOOλ的 Tuple.collectors()方法做这件事,这个方法将两个聚集器合并成一个新的聚集器 ,而这个新的collector会返回单独集合组成的元组.

代码比上面的描述说的更清楚.Mykong.com的那段代码可以替换为如下代码:

 Tuple2, List> result =  map.entrySet()     .stream()     .collect(Tuple.collectors(         Collectors.mapping(Entry::getKey, Collectors.toList()),         Collectors.mapping(Entry::getValue, Collectors.toList())     )); 

在这儿唯一跟jOOλ有关的代码是这个调用:Tuple.collectors(),这个调用在将键和值聚集为list之前,合并了多个在Map entries上进行映射的标准JDK聚集器.

打印上面结果时,你会得到:

 ([50, 20, 40, 10, 30], [dragonfruit, orange, watermelon, apple, banana]) 

即一个包含结果list的元组.

再简化下,不使用Java 8 Stream API,使用 jOOλ的Seq(针对串行流),那么我们可以写下如下更短的代码作为替代:

 Tuple2, List> result =  Seq.seq(map)    .collect(         Collectors.mapping(Tuple2::v1, Collectors.toList()),         Collectors.mapping(Tuple2::v2, Collectors.toList())    ); 

相比前一个例子,此处的 Collectable.collect(Collector, Collector)提供了非常棒的语法糖

更多精彩内容以及学习资料,尚学堂论坛bbs.bjsxt.com免费下载。

  • 北京校区
  • 西安校区
  • 山西校区
  • 武汉校区
  • 深圳校区
  • 上海校区
  • 广州校区
  • 保定招生办
  • 黑龙江项目办

北京京南校区:北京亦庄经济开发区科创十四街6号院1号楼 赛蒂国际工业园
咨询电话:400-009-1906 / 010-56233821
面授课程: JavaEE+微服务+大数据     大数据+机器学习+平台架构     Python+数据分析+机器学习  人工智能+模式识别+强化学习   WEB前端+移动端+服务端渲染

地址:陕西省西安市高新区西安软件园西区创新信息大厦A座三层尚学堂

电话:029-88228155 / 18291433445

山西学区地址:山西省晋中市榆次区大学城大学生活广场万科商业A1座702

武汉学区地址:武汉市东湖高新区光谷金融港B22栋11楼
咨询电话:027-87989193

深圳校区地址:深圳市宝安区航城大道U8智造产业园U6栋3楼
咨询电话:0755-23061965 / 18898413781

上海尚学堂校区地址:上海市浦东新区城丰路650号
咨询电话:021-67690939

广州校区地址:广州市天河区车陂街道大岗路5号中侨广场2栋321室(四号线车陂站D出口,或brt车陂站)
咨询电话:18948349646

保定招生办公室

地址:河北省保定市竞秀区朝阳南大街777号鸿悦国际1101室

电话:15132423123

黑龙江项目办
地点:哈尔滨市松北区博文路青年部落孵化器1层
电话:15321415678
Copyright 2006-2021 北京尚学堂科技有限公司  京ICP备13018289号-19  京公网安备11010802015183  
网站维护:北京尚学堂科技有限公司昌平分公司