Java:List转Map (用stream实现)_java stream list转map-程序员宅基地

技术标签: java  特殊功能实现  list  map  

 前言:JDK1.8及其以上,才支持下面案例
 
//实体类
public class Student {
    
    private  String no;  //学号
    private  String name;	//姓名
    private  Integer age; //年龄
    //构造方法忽略
    //set、get 方法忽略
}
public class Teacher{
    
    private  String no;  //教师号
    private  String name; //姓名
    private  Integer age; //年龄
}

一、List<Object>Map<String, String>

//注意事项 
//在使用java.util.stream.Collectors 类的 toMap()方法转为 Map集合时,一定要注意当Map的value为null时会抛空指针异常!!!(如:下面示例的getName不可为空!!!)

//声明一个List集合
List<Student> list = new ArrayList();  
	 list.add(new Student("1001", "小A", 15));  
	 list.add(new Student("1001", "小B", 20));//学号重复(下面特殊处理)
	 list.add(new Student("1002", "小C", 15));
	 list.add(new Student("1003", "小D", 30));
       
//将list转map 【key为1个属性,value为1个属性】  (map的键重复不会报错,下面已经处理)(注意:getName不可为空!!!)
Map<String, String> map =
	list.stream().collect(Collectors.toMap( 
		Student::getNo, 
		Student::getName,
	    (key1 , key2) -> key1 
	));
	
//将list转map 【key为多个属性,value为1个属性】  (map的键重复不会报错,下面已经处理)(注意:getName不可为空!!!)
Map<String, String> map =
	list.stream().collect(Collectors.toMap( 
		obj -> obj.getNo() + "_" + obj.getName(),
		Student::getName,
	    (key1 , key2) -> key1 
	));

二、List<Object>Map<String, Object> (返回对象本身)

//声明一个List集合
List<Student> list = new ArrayList();
	list.add(new Student("1001", "小A", 15));  
	 list.add(new Student("1001", "小B", 20));
	 list.add(new Student("1002", "小C", 15));
	 list.add(new Student("1003", "小D", 30));

//将list转map 【key为1个属性,value为对象本身】  (map的键去重)
Map<String, Student> map = 
 	list.stream().collect(Collectors.toMap( 
	 	Student::getNo, 
	    obj -> obj, 
	    (key1 , key2) -> key1 
    ));
    
或者

//将list转map 【key为1个属性,value为对象本身】  (map的键去重)
Map<String, Student> map = 
 	list.stream().collect(Collectors.toMap( 
	 	Student::getNo, 
	    Function.identity(), 
	    (key1 , key2) -> key1 
    ));
    
或者

//将list转map 【key为多个属性,value为对象本身】 (map的键去重)
Map<String, Student> map = 
 	list.stream().collect(Collectors.toMap( 
	 	obj -> obj.getNo() + "_" + obj.getName(),
	    obj -> obj, 
	    (key1 , key2) -> key1 
    ));
	

三、List<Object1>Map<String, Object2> (返回另一个对象)

//声明一个List集合
List<Student> list = new ArrayList();
	list.add(new Student("1001", "小A", 15));  
	list.add(new Student("1001", "小B", 20));
	list.add(new Student("1002", "小C", 15));
	list.add(new Student("1003", "小D", 30));

//将list转map 【key为1个属性,value为另一个对象】 (map的键去重)
Map<String, Teacher> map = 
	list.stream().collect(Collectors.toMap(
	    Student::getNo, 
		stu -> {
    
            Teacher teacher = new Teacher();
            teacher.setNo(stu.getNo());
            teacher.setName(stu.getName());
            return teacher;
        },  
        (key1 , key2) -> key1
    ));

四、List<Object>Map<String, List<Object>> (分组)【以1个字段分/以多个字段 只分1次组】

//声明一个List集合
List<Student> list = new ArrayList();
   list.add(new Student("1001", "小A", 15));  
   list.add(new Student("1001", "小B", 20));
   list.add(new Student("1002", "小C", 15));
   list.add(new Student("1003", "小D", 30));

//将list转map  【key为1个属性,value为相同key的集合】 (以某1个属性来分组,将分组后相同键对应的对象放在一起)[备注:value数组没有排序]
Map<String, List<Student>> map = 
   list.stream().collect( Collectors.groupingBy(Student::getNo) );


//将list转map 【key为多个属性,value为相同key的集合】 (以多个属性来分组,将分组后相同联合键对应的对象放在一起)[备注:value数组没有排序]
Map<String, List<Student>> map = 
   list.stream().collect( Collectors.groupingBy(obj -> obj.getNo + "_" + obj.getName) );

//tips: 上面遍历的时候,可以这样写:
map.forEach( (oneKey, students) -> {
    
          
});

//[备注:value数组做了排序] 这个使用比较少见
Map<String, List<Student>> mapPaiXu = list.stream().collect(Collectors.groupingBy(Student::getNo, TreeMap::new, Collectors.toList()));

五、List<Object>Map<String, List<String>> (分组)【针对后面的集合,只提取Object里面的某个字段,而不是源对象Object】

//声明一个List集合
List<Student> list = new ArrayList();
   list.add(new Student("1001", "小A", 15));  
   list.add(new Student("1001", "小B", 20));
   list.add(new Student("1002", "小C", 15));
   list.add(new Student("1003", "小D", 30));

//将list转map  【key为1个属性,value为相同key的集合对象中的某个字段】 (以某1个属性来分组,将分组后相同键对应的对象数组 中的某个字段放在一起)
Map<String, List<String>> map = 
   list.stream().collect(  Collectors.groupingBy(Student::getNo, Collectors.mapping(Student::getName,Collectors.toList())) );

//tips: 上面遍历的时候,可以这样写:
map.forEach( (no, names) -> {
    
          
});

六、List<Object>Map<String, String> (分组+拼接)【针对后面的集合,只提取Object里面的某个字段,再拼接在一起】

//声明一个List集合
List<Student> list = new ArrayList();
   list.add(new Student("1001", "小A", 15));  
   list.add(new Student("1001", "小B", 20));
   list.add(new Student("1002", "小C", 15));
   list.add(new Student("1003", "小D", 30));

//将list转map  【key为1个属性,value为相同key的集合对象中的某个字段】 (以某1个属性来分组,将分组后相同键对应的对象集合 中的某个字段拼接在一起,成为一个字符串)
Map<String, String> map1 = 
   list.stream().collect(  Collectors.groupingBy(Student::getNo, Collectors.mapping(Student::getName, Collectors.joining(","))) );
Map<String, String> map2 = 
   list.stream().collect(  Collectors.groupingBy(Student::getNo, Collectors.mapping(Student::getName, Collectors.joining("," , "[", "]"))) );

//tips: 上面遍历的时候,可以这样写:
map.forEach( (no, names) -> {
    
          
});

七、List<Object>Map<String, Set<String>> (分组)【针对后面的集合,只提取Object里面的某个字段,而不是源对象Object】

//声明一个List集合
List<Student> list = new ArrayList();
   list.add(new Student("1001", "小A", 15));  
   list.add(new Student("1001", "小B", 20));
   list.add(new Student("1002", "小C", 15));
   list.add(new Student("1003", "小D", 30));

//将list转map  【key为1个属性,value为相同key的集合对象中的某个字段】 (以某1个属性来分组,将分组后相同键对应的对象数组 中的某个字段放在一起)
Map<String, Set<String>> map = 
   list.stream().collect(  Collectors.groupingBy(Student::getNo, Collectors.mapping(Student::getName, Collectors.toSet())) );

//tips: 上面遍历的时候,可以这样写:
map.forEach( (no, names) -> {
    
          
});

八、List<Object>Map<String, Map<String, List<Student>>> (分组)【先根据某个字段分组,再根据另一个字段分组,一共分2个层级的组】

//声明一个List集合
List<Student> list = new ArrayList();
   list.add(new Student("1001", "小A", 15));  
   list.add(new Student("1001", "小B", 15));
   list.add(new Student("1001", "小C", 20));  
   list.add(new Student("1002", "小D", 15));
   list.add(new Student("1003", "小E", 30));

//将list转map  【第一个key为1个属性,第二个key为另1个属性,value为分组后的对象集合】
//下面例子解释:第一个key是学号,第二个key是年龄,最后的值是相同学号,相同年龄的对象集合
Map<String, Map<String, List<Student>>>  map = 
   list.stream().collect(  Collectors.groupingBy(Student::getNo, Collectors.groupingBy(Student::getAge)) );


五、学习链接:

https://blog.csdn.net/qq_39629277/article/details/83012548
https://blog.csdn.net/lu930124

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/SeniorShen/article/details/120061248

智能推荐

未来不是计算机发展的方向,未来人类的方向,或许不是人工智能,而是智能人类...-程序员宅基地

文章浏览阅读148次。原标题:未来人类的方向,或许不是人工智能,而是智能人类未来人类的方向,或许不是人工智能,而是智能人类进入互联网时代以来,我们的科技发展速度是越来越快。从工业革命到后来的信息时代、原子时代和现在的智能时代,人类的科技发展周期越来越短,我们似乎进入到了一个技术大爆炸的时代。对此许多人很好奇,我们人类未来的方向是什么?之前我们一直都认为是人工智能,但是科学家们也提出了另一个方向,那就是智能人类。 其实关..._兰森环游世界

攻防世界 Web_php_unserialize 反序列化_php_unserialize_pro小明已经学会反序列化啦!但是这道题有点难呢?怎么办呢?-程序员宅基地

文章浏览阅读335次,点赞2次,收藏2次。昨天帮忙打了场比赛,web题目里也是有反序列化的题,也是利用魔术方法的调用来构造pop链,获取flag但那道题好绕我不会写,然后还有关于json的题,就发现自己好多都没学,真的打一场比赛容易把自己人都打傻掉。这道题也是看了好久才明白的题目。废话不多直接上代码 <?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file =_php_unserialize_pro小明已经学会反序列化啦!但是这道题有点难呢?怎么办呢?

Matlab GUI,坐标轴控件,画sin函数_maltab gui 滑动sin函数-程序员宅基地

文章浏览阅读9.6k次,点赞2次,收藏21次。guide (代码:1\gui_biancheng.m)% 打开窗体钱先执行该函数function gui_biancheng_OpeningFcn(hObject, eventdata, handles, varargin)handles.output = hObject;handles.x=-pi:0.01:pi; %全局变量guidata(hObject, handle_maltab gui 滑动sin函数

fastjson解析json数组-程序员宅基地

文章浏览阅读5.3k次。import java.util.ArrayList;import java.util.List;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.montnets.ott.entity.weix.OtWeiBatchgetMaterial;import com...._fastjson解析json数组

python入门(坐标相加)_python怎么对坐标加减-程序员宅基地

文章浏览阅读6.6k次。坐标相加_python怎么对坐标加减

kotlin的RxJava进阶为RxJava2-程序员宅基地

文章浏览阅读3.5k次。RxJava进阶RxJava2最近在之前做项目的时候用RxJava,后来了解了RxJava2后决定让项目的RxJava进阶为RxJava2。RxJava 2在Reactive-Streams规范的基础上完全重写。规范本身已经从RxJava发展而来,在使用RxJava2之前可以不需要学习RxJava。Maven地址和基础包观察者模式kotlin代码总结Maven地址和基

随便推点

隧道凿岩机器人传感器_凿岩机器人钻臂GPC-PID双模控制-程序员宅基地

文章浏览阅读115次。凿岩机器人钻臂GPC-PID双模控制黄开启;王雷坤【期刊名称】《《传感器与微系统》》【年(卷),期】2019(000)011【摘要】为避免广义预测控制(GPC)起始阶段存在因所获信息少而对双三角钻臂造成的控制不稳定,以及计算中因矩阵不可逆而造成的数值病态,提出以GPC和比例—积分—微分(PID)控制为基础的双模式自适应控制策略.根据广义预测PID算法得出在线更新的自校正参数,以此参数是否在规定范围..._凿岩钻机配套传感器

matlab3阶幺矩阵,Matlab操作矩阵的相关方法-程序员宅基地

文章浏览阅读3.7k次,点赞3次,收藏12次。Matlab操作矩阵的相关方法下面这篇文章主要是对吴恩达老师机器学习中matlab操作的一个整理和归纳一、基本操作1.生成矩阵(ones、zeros)A = [1 2;3 4;5 6] #生成3行4列的矩阵B = [1 2 3] #B就是一个行向量C = [1;2;3] #定义c为一个列向量..._三阶单位矩阵在matlab

React Js 实现锚点定位的集中方法-程序员宅基地

文章浏览阅读3k次。React Js 实现锚点定位的集中方法注:以水平锚点定位为例,垂直方向亦如此方法1. url hash值跳转到达页面可视位置,滚动区域的左/右边,无滚动的平滑效果,效果差。设置,用户点击并跳转<a href="#anchorId">锚点1</a>待跳转..._react锚点定位

Vue+ElementUI实现表单动态渲染、可视化配置的方法-程序员宅基地

文章浏览阅读1.5k次。这篇文章主要介绍了Vue+ElementUI实现表单动态渲染、可视化配置的方法,需要的朋友可以参考下动态渲染就是有一个异步的数据,大概长这样:{"inline": true,"labelPosition": "right","labelWidth": "","size": "small","statusIcon": true,"formItemList": [{"type": "input","l..._vue3 element-ui 多选框label使用html渲染方法

工作三年 性能调优没有学好 让我和阿里offer直接擦肩而过~_工作中从没用过内存调优-程序员宅基地

文章浏览阅读4.3k次,点赞18次,收藏52次。目录前言JVM组成解析栈和栈帧JVM指令码:局部变量表操作数栈动态链接方法出口程序计数器为什么要设计程序计数器?堆内存先介绍一下堆内存的构成:这里提一下jvm的垃圾回收算法可以通过java自带的jvisualvm来看一下内存的变化提一下关于jvm调优方法区本地方法栈最后前言面试经常被问 JVM如何调优?这个问题该怎么回答,其实真的没调过。有JVM调优经验的人能回答下怎么调优和调优后的效果?JVM调优对现在的研发和整个系统线上运_工作中从没用过内存调优

python举例-详解7类Python运算符及代码举例-程序员宅基地

文章浏览阅读317次。导读:运算这一概念起源于数学,即通过运算法使参与运算的元素得出确定且可重复的结果。作为计算机的核心功能,运算架构起计算机系统的逻辑体系。计算机运算并不局限于普通的数学计算,它更贴近于"逻辑推算”这一概念,其根本目的就是实现逻辑推算。运算符是运算法则的具体体现。Python提供了算术运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、身份运算符和成员运算符7类运算符,从而实现了丰富多样的..._python数学符号运算例子

推荐文章

热门文章

相关标签