java8 List的Stream流操作 (特别篇 二) toMap

Stream API 借助于Lambda表达式,极大的提高编程效率和程序可读性、可以执行非常复杂的查找、过滤和映射数据等操作。

在java8 List的Stream流操作 (常用篇 一)中主要写了 遍历、过滤、查询、去重、排序、分组等

本文主要写主要的操作之一 map集合

目录

1、简单组装 (但是 key(userId) 重复会报错)(不推荐)

2、组装成map key值取前面的(重复情况下)

3、组装成map key值取后面的(重复情况下)

4、组装成map  key值取累加或者拼接(重复情况下)

5、组装成map 先通过性别分组再统计性别年龄总和

6、组装成 Map> 根据userId 组装list对象,对应userId的对象的某个属性成组(userName),list

7、以userId为key  以User对象为值 Map,>


 还是首先给出我们的数据前提

User实体(用户信息) 
package com.shanghai.zrlshanghaih5service.man.vo;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Date;

/**
 * @CreateTime:  xxxx
 * @Description: User
 * @Version: 1.0
 */
@Data
public class User {

    @ApiModelProperty(value = "用户id")
    private Integer userId;

    @ApiModelProperty(value = "用户名称")
    private String userName;

    @ApiModelProperty(value = "用户性别")
    private String sex;

    @ApiModelProperty(value = "用户生日")
    private Date birthday;

    @ApiModelProperty(value = "用户年龄")
    private Integer age;

    @ApiModelProperty(value = "用户是否激活")
    private boolean bl;

    public User(Integer userId, String userName, String sex, Integer age, boolean bl) {
        this.userId = userId;
        this.userName = userName;
        this.sex = sex;
        this.age = age;
        this.bl = bl;
    }

}
        List userList = Lists.newArrayList();
        userList.add(new User(1,"天一","男",16,true));
        userList.add(new User(2,"空二","女",19,true));
        userList.add(new User(3,"张三","男",18,true));
        userList.add(new User(4,"李四","女",38,true));
        userList.add(new User(5,"王五","男",18,true));
        userList.add(new User(5,"王六","男",18,true));
        userList.add(new User(5,"王七","男",18,true));

1、简单组装 (但是 key(userId) 重复会报错)(不推荐)

// 组装成map
// key(userId) 重复会报错
Map map1 = userList.stream().collect(Collectors.toMap(User::getUserId, User::getUserName));
log.info("key重复会报错:{},map1);

key 不能有重复,如果重复则需要使用合并函数取默认值,否则会报错,因为 Map 的 key 不能重复。

2、组装成map key值取前面的(重复情况下)

Map map2 = userList.stream().collect(Collectors.toMap(User::getUserId, User::getUserName, (v1, v2) -> v1));
log.info("组装成map 值取前面kay的值 map2:{}",map2);

输出结果:组装成map 值取前面kay的值 map2:{1=天一, 2=空二, 3=张三, 4=李四, 5=王五}

3、组装成map key值取后面的(重复情况下)

Map map3 = userList.stream().collect(Collectors.toMap(User::getUserId, User::getUserName, (v1, v2) -> v2));
log.info("组装成map 后面kay的值 map3:{}",map3);

结果集:组装成map 后面kay的值 map3:{1=天一, 2=空二, 3=张三, 4=李四, 5=王七}

4、组装成map  key值取累加或者拼接(重复情况下)

Map map4 = userList.stream().collect(Collectors.toMap(User::getUserId, User::getUserName, (v1, v2) -> v1+v2));
Map map41 = userList.stream().collect(Collectors.toMap(User::getUserId, User::getUserName, (v1, v2) -> v1+","+v2));
log.info("组装成map key值取累加 map4:{}",map4);
log.info("组装成map key值取拼接累加 map41:{}",map41);

5、组装成map 先通过性别分组再统计性别年龄总和

userList.stream().collect(Collectors.groupingBy(User::getSex)).forEach((key,value)->{
    Map sexAndAge = value.stream().collect(Collectors.toMap(User::getSex, User::getAge, Integer::sum));
    sexAndAge.forEach((k,v) ->{
        log.info("组装成map 先通过性别分组再统计性别年龄总和 性别:{}, 年龄总和:{}",k,v);
    });

});

结果集:

组装成map 先通过性别分组再统计性别年龄总和 性别:女, 年龄总和:57

组装成map 先通过性别分组再统计性别年龄总和 性别:男, 年龄总和:88

觉得复杂的可以拆分成两行代码(先分组-》再求和

先分组

Map> collect = userList.stream().collect(Collectors.groupingBy(User::getSex));

再求和

collect.forEach((key,value)->{
    Map sexAndAge = value.stream().collect(Collectors.toMap(User::getSex, User::getAge, Integer::sum));
    sexAndAge.forEach((k,v) ->{
        log.info("组装成map 先通过性别分组再统计性别年龄总和 性别:{}, 年龄总和:{}",k,v);
    });

});

6、组装成 Map> 根据userId 组装list对象,对应userId的对象的某个属性成组(userName)

Map> map5 = userList.stream().collect(Collectors.groupingBy(User::getUserId, Collectors.mapping(User::getUserName, Collectors.toList())));
log.info("组装成 Map> map5:{}",map5);

结果集:组装成 Map> map5:{1=[天一], 2=[空二], 3=[张三], 4=[李四], 5=[王五, 王六, 王七]}

还有一种方式:

Map> map6 = userList.stream().collect(Collectors.toMap(User::getUserId,
    p ->  {
        List getNameList = new ArrayList<>();
        getNameList.add(p.getUserName());
        return getNameList;
    },
    (List value1, List value2) -> {
            value1.addAll(value2);
        return value1;
    }
));
log.info("组装成map map6:{}",map6);

结果集:组装成map map6:{1=[天一], 2=[空二], 3=[张三], 4=[李四], 5=[王五, 王六, 王七]}

7、以userId为key  以User对象为值 Map

// 以userId为key  以User对象为值 Map
 Map map7 = userList.stream()
.filter(distinctByKey(User::getUserId))
.collect(Collectors.toMap(User::getUserId, User -> User));
log.info("以userId为key  以User对象为值 map7:{}",map7);
/** key是否存在 **/
public static  Predicate distinctByKey(Function keyExtractor) {
   Map seen = new ConcurrentHashMap<>();
   return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

以userId为key  以User对象为值 
map7:{1=User(userId=1, userName=天一, sex=男, birthday=null, age=16, bl=true), 
2=User(userId=2, userName=空二, sex=女, birthday=null, age=19, bl=true), 
3=User(userId=3, userName=张三, sex=男, birthday=null, age=18, bl=true), 
4=User(userId=4, userName=李四, sex=女, birthday=null, age=38, bl=true), 
5=User(userId=5, userName=王五, sex=男, birthday=null, age=18, bl=true)}

你可能感兴趣的:(java基础,数据结构,java高级,Stream流,toMap,数据结构,java)