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

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<Integer, 实体类> map = two.stream()
                .collect(Collectors.toMap(实体类::getMatchRingId, match -> match));
        // 重复问题
        /*
         * Map<Integer, 实体类> 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<User> 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<User> getNoRepeatList(List<User> oldList){
        List<User> 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<Map<String, Object>> orgList使用stream解析
Map<String,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("map的key值").toString()));
此方法使用场景,如想使用orgList中map的value值分组
使用此方法,有个缺陷,如果map的value为空,会抛出空指针异常,示例如下:

 public static void main(String[] args) {
        List<Map<String, Object>> orgList=new ArrayList<>();
        Map<String,Object> one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map<String,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("你好").toString()));
        System.out.println(list.toString());
    }
输出结果:
{有值=[{你好=有值, 空值=null}]}
 public static void main(String[] args) {
        List<Map<String, Object>> orgList=new ArrayList<>();
        Map<String,Object> one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map<String,List<Map<String,Object>>> 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<Map<String, Object>> orgList=new ArrayList<>();
        Map<String,Object> one=new HashMap<>();
        one.put("你好","有值");
        one.put("空值",null);
        orgList.add(one);
        Map<Optional<String>,List<Map<String,Object>>> 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<User> userList){
    //此时这里会抛出空指针异常
    Map<String, List<User>> userMap = userList.stream.collect(Collectors.groupingBy(x -> x.getSex()));
}

解决方案

public void groupBy(List<User> userList){
    //使用option包装一层
    Map<Option<String>, List<User>> 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<UserPO> users = new ArrayList<>();
        users.add(user1);
        users.add(user2);
        users.add(user3);

        //2. 过滤list中对象的某个属性非空,然后返回一个新的list
        List<UserPO> 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<String, String> 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问题

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

        ArrayList<Map<String, String>> 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<Map<String, String>> list = new ArrayList<>();
 
        {
            Map<String, String> map = new HashMap<>();
            map.put("id", "1");
            map.put("name", "B");
            map.put("age", "C");
            list.add(map);
        }
 
        {
            Map<String, String> map = new HashMap<>();
            map.put("id", "1");
            map.put("name", "E");
            map.put("age", "F");
            list.add(map);
        }
 
        //1.返回结果{"1","B"},{"2","E"}
//        Map<String, String> 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<String, Map> b = list.stream().collect(Collectors.toMap(l -> l.get("id"), map -> map));
//        Map<String, Map> c = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity()));
 
        //3.重复key情况下处理方式返回结果{"1":{"name":"E","id":"1","age":"F"}}
//        Map<String, 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<String, 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<String, List<Map>> lableGbType = list.stream().collect(Collectors.groupingBy(l -> (String) l.get("id")));
 
        //6.根据key提取list中指定的值转List数组;返回结果["1","1"]
//        List<String> ids = list.stream().map(m -> (String) m.get("id")).collect(Collectors.toList());
 
 
        //7.数组去重并转list
      /*  String[] str = "1,1,2,3,4,5,".split(",");
        List<String> listNames = Arrays.stream(str).filter(name -> !isEmpty(name)).distinct().collect(Collectors.toList());*/
 
    }

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

原代码如下:

public static List<Map<String, Object>> toListMap(List<User> userList) {
    List<Map<String, Object>> result = new ArrayList<>();
    Map<String, Object> 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<String, Object> toMap(User user) {
    Map<String, Object> map = new HashMap<>();
    map.add("username", user.getUserName);
    map.add("age", user.getAge);
    map.add("gender", user.getGender);
    return map;
}
 
List<Map<String, Object>> data = userList.stream()
                .map(this::toMap)
                .collect(Collectors.toList());
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342