使用java8的stream把list转map,并将两个list的数据对象合并

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ceshi {
    public static void main(String[] args) {
        List<实体类> one = new ArrayList<>();
        实体类 vo = new 实体类();
        vo.setMatchRingId(12345);
        vo.setBoss1BetCount("值1");
        vo.setBoss2BetCount("值2");
        vo.setWinType(1);
        vo.setRewardCount("值3");
        vo.setRingType(4);
        vo.setPump("值5");
        one.add(vo);

        List<实体类> two = new ArrayList<>();
        实体类 vos = new 实体类();
        vos.setMatchRingId(12345);
        vos.setNzTotal("99999");
        vos.setAbTotal("88888");
        two.add(vos);
        System.out.println("集合1长度:" + one.size() + "==集合2长度:" + two.size());
        Map map = two.stream()
                .collect(Collectors.toMap(实体类::getMatchRingId, match -> match));
        // 重复问题
        /*
         * Map keyRedo = one.stream()
         * .collect(Collectors.toMap(实体类::getMatchRingId, Function.identity(),
         * (key1, key2) -> key2));
         */
        // 合并
        one.forEach(n -> {
            // 如果等级一致
            if (map.containsKey(n.getMatchRingId())) {
                实体类 obj = map.get(n.getMatchRingId());
                // 把数量复制过去
                n.setAbTotal(obj.getAbTotal());
                n.setNzTotal(obj.getNzTotal());
            }
        });

        one.forEach(m -> {
            System.out.println(m.getMatchRingId() + "==" + m.getNzTotal() + "==" + m.getPump());
        });

    }
}

java stream处理list根据多个字段判断重复
List去重复 ,我们首先想到的可能是 利用List转Set 集合,因为Set集合不允许重复。 所以达到这个目的。 如果集合里面是简单对象,例如Integer、String等等,这种可以使用这样的方式去重复。但是如果是复杂对象,即我们自己封装的对象。用List转Set 却达不到去重复的目的。 所以,回归根本。 判断Object对象是否一样,我们用的是其equals方法。 所以我们只需要重写equals方法,就可以达到判断对象是否重复的目的。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import org.apache.commons.collections.CollectionUtils;
 
 
public class TestCollection {
 
    //去重复之前集合
    private static  List list = Arrays.asList(
            new User("张三", BigDecimal.valueOf(35.6), 18),
            new User("李四", BigDecimal.valueOf(85), 30),
            new User("赵六", BigDecimal.valueOf(66.55), 25),
            new User("赵六", BigDecimal.valueOf(66.55), 25),
            new User("张三", BigDecimal.valueOf(35.6), 18));
    
    public static void main(String[] args) {
        //排除重复
        getNoRepeatList(list);
        
    }
    
    /**
     * 去除List内复杂字段重复对象
     * @param oldList
     * @return
     */
    private static List getNoRepeatList(List oldList){
        List list = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(oldList)){
            for (User user : oldList) {
                //list去重复,内部重写equals
                if(!list.contains(user)){
                    list.add(user);
                }
            }
        }
        
        //输出新集合
        System.out.println("去除重复后新集合:");
        if(CollectionUtils.isNotEmpty(list)){
            for (User user : list) {
                System.out.println(user.toString());
            }
        }
        return list;        
    } 
    
    static class User{
        private String userName; //姓名
        private BigDecimal score;//分数
        private Integer age;
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
        public BigDecimal getScore() {
            return score;
        }
        public void setScore(BigDecimal score) {
            this.score = score;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        public User(String userName, BigDecimal score, Integer age) {
            super();
            this.userName = userName;
            this.score = score;
            this.age = age;
        }
        public User() {
            // TODO Auto-generated constructor stub
        }
        
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "姓名:"+ this.userName + ",年龄:" + this.age + ",分数:" + this.score;
        }
        
        /**
         * 重写equals,用于比较对象属性是否包含
         */
        public boolean equals(Object obj) {  
            if (obj == null) {  
                return false;  
            }  
            if (this == obj) {  
                return true;  
            }  
            User user = (User) obj;  
            //多重逻辑处理,去除年龄、姓名相同的记录
            if (this.getAge() .compareTo(user.getAge())==0
                    && this.getUserName().equals(user.getUserName())
                    && this.getScore().compareTo(user.getScore())==0) {  
                return true;  
            }  
            return false;  
        }  
    }
    
}

执行结果:

去除重复后新集合:
姓名:张三,年龄:18,分数:35.6
姓名:李四,年龄:30,分数:85
姓名:赵六,年龄:25,分数:66.55

List> orgList使用stream解析
Map>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("map的key值").toString()));
此方法使用场景,如想使用orgList中map的value值分组
使用此方法,有个缺陷,如果map的value为空,会抛出空指针异常,示例如下:

 public static void main(String[] args) {
        List> orgList=new ArrayList<>();
        Map one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("你好").toString()));
        System.out.println(list.toString());
    }
输出结果:
{有值=[{你好=有值, 空值=null}]}
 public static void main(String[] args) {
        List> orgList=new ArrayList<>();
        Map one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("空值").toString()));
        System.out.println(list.toString());
    }
输出结果:
Exception in thread "main" java.lang.NullPointerException
    at net.sppan.base.util.集合解析.lambda$main$0(集合解析.java:16)

可以使用Optional.ofNullable(obj)

传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).
Optional.of(obj)
它要求传入的 obj 不能是 null 值的, 否则 NullPointerException.

使用场景:

  1. 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时;
  2. 当obj 为 null 立即报告 NullPointException 异常, 而不是隐藏空指针异常时.
    Optional.empty()
    内部value是null
public static void main(String[] args) {
        List> orgList=new ArrayList<>();
        Map one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map,List>> list=orgList.stream().collect(Collectors.groupingBy(e-> Optional.ofNullable(String.valueOf(e.get("空值")))));
        System.out.println(list.toString());
    }
输出结果:
{Optional[null]=[{你好=有值, 空值=null}]}

Stream的Collectors.groupingBy支持key为null进行分组

场景

在使用Collectors.groupingBy分组时,如果分组的字段中有值为null,会抛出空指针异常
例如:

// An highlighted block
calss User{
    private Integer age;
    private String sex;
}

public static void main(String[] args){
    User user1 = new User(18, "女");
    User user2 = new User(19, "女");
    User user3 = new User(20, "男");
    //没有性别的人需要用null表示
    User user4 = new User(18, null);
    groupBy(Arrays.aslist(user1,user2,user3,user4))
    
}
//对用户按照年纪分组
public void groupBy(List userList){
    //此时这里会抛出空指针异常
    Map> userMap = userList.stream.collect(Collectors.groupingBy(x -> x.getSex()));
}

解决方案

public void groupBy(List userList){
    //使用option包装一层
    Map, List> userMap = userList.stream.collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getSex())));
}
过滤list中对象的某个属性非空,然后返回一个新的list
import com.example.demo.entity.UserPO;
import com.google.common.collect.Maps;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 过滤list中对象的某个属性非空,然后返回一个新的list
 */
public class LambdaForList {
    public static void main(String[] args) {
        //1. 初始化数据
        UserPO user1 = new UserPO(1, "java");
        UserPO user2 = new UserPO(2, "C");
        UserPO user3 = new UserPO(null, "PHP");
        List users = new ArrayList<>();
        users.add(user1);
        users.add(user2);
        users.add(user3);

        //2. 过滤list中对象的某个属性非空,然后返回一个新的list
        List newUsers = users.stream()
                .filter((UserPO user) -> user.getId() !=null).collect(Collectors.toList());

        newUsers.forEach((UserPO user) ->
                System.out.println(user.getName() + "--->" + user.getId()
        ));
    }
}
输出:
java--->1
C--->2
JDK8 Lamdba表达式转换成Map,value为null问题
// 将list转换成Map类型
Map map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName));
// 如果报 map里的value空指针异常,则需要在value,也就是toMap()的第二个参数进行空(null)值的判断逻辑;例如:也就是  Person::getName 改成 p -> p.getName()==null?"":p.getName()就可以解决value为null问题

//  Collector> java.util.stream.Collectors.toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)
// toMap()第三个参数是当有重复的Key时,会执行这段逻辑,传入2个参数,第一个参数是已经存在Map的value值,第二个是即将覆盖的value值,最终返回哪个值为准
stream将List转map,解决Duplicate key异常
public static void main(String[] args) {
        List> list = new ArrayList<>(16) ;
        Map map1 = new HashMap<>(16);
        map1.put("key1", "val1");
        Map map2 = new HashMap<>(16);
        map2.put("key1", "val1");
        list.add(map1);
        list.add(map2);
        //打印list里面的数据
        list.forEach(System.out::println);

        ArrayList> data = list.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                        () -> new TreeSet<>(Comparator.comparing(m -> m.get("key1")))), ArrayList::new));
         System.out.println("=======去重前后分界线=======");
         //打印过滤后的数据
         data.forEach(System.out::println);
    }
    }
    
打印结果如下:

{key1=val1}
{key1=val1}
=======去重前后分界线=======
{key1=val1}
public static void main(String[] args) {
 
        List> list = new ArrayList<>();
 
        {
            Map map = new HashMap<>();
            map.put("id", "1");
            map.put("name", "B");
            map.put("age", "C");
            list.add(map);
        }
 
        {
            Map map = new HashMap<>();
            map.put("id", "1");
            map.put("name", "E");
            map.put("age", "F");
            list.add(map);
        }
 
        //1.返回结果{"1","B"},{"2","E"}
//        Map a = list.stream().collect(Collectors.toMap(l -> l.get("id"), l -> l.get("name")));
 
        //2.两种方法返回结果{"1":{"name":"B","id":"1","age":"C"},"2":{"name":"E","id":"2","age":"F"}}
//        Map b = list.stream().collect(Collectors.toMap(l -> l.get("id"), map -> map));
//        Map c = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity()));
 
        //3.重复key情况下处理方式返回结果{"1":{"name":"E","id":"1","age":"F"}}
//        Map d = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity(), (key1, key2) -> key2));
 
        //4.重复key情况下指定返回数据类型处理方式返回结果{"1":{"name":"E","id":"1","age":"F"}}
//        Map e = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));
 
 
        //5.list根据key合并并转map;返回结果{"1":[{"name":"B","id":"1","age":"C"},{"name":"E","id":"1","age":"F"}]}
//        Map> lableGbType = list.stream().collect(Collectors.groupingBy(l -> (String) l.get("id")));
 
        //6.根据key提取list中指定的值转List数组;返回结果["1","1"]
//        List ids = list.stream().map(m -> (String) m.get("id")).collect(Collectors.toList());
 
 
        //7.数组去重并转list
      /*  String[] str = "1,1,2,3,4,5,".split(",");
        List listNames = Arrays.stream(str).filter(name -> !isEmpty(name)).distinct().collect(Collectors.toList());*/
 
    }

使用Java 8 Stream将List(Object)转成List(Map(String, Object))
问题描述:有一个用户列表List,须将每个User部分字段提取出来,重新放入一个Map中,然后将生成的Map放入List中。

原代码如下:

public static List> toListMap(List userList) {
    List> result = new ArrayList<>();
    Map map;
    for (User user : userList) {
       map = new HashMap<>();
       map.add("username", user.getUserName);
       map.add("age", user.getAge);
       map.add("gender", user.getGender);
       result.add(map);
    }
    return result;
}
使用Java 8 stream后,代码如下:
private Map toMap(User user) {
    Map map = new HashMap<>();
    map.add("username", user.getUserName);
    map.add("age", user.getAge);
    map.add("gender", user.getGender);
    return map;
}
 
List> data = userList.stream()
                .map(this::toMap)
                .collect(Collectors.toList());

你可能感兴趣的:(使用java8的stream把list转map,并将两个list的数据对象合并)