Java把多个list 合并成一个并删除重复元素

摘要:介绍合并多个list并删除其中重复元素的方法,推荐使用Map或者TreeSet去重。

综述

  开发过程中遇到一个合并去重问题,需求完成后,总结出来一个比较简单的方法。对于List中不同类型的数据,需要采用不同的处理方式。List中如果是基础数据类型,直接合并去重即可;如果是对象类型,则需要借助Map去重,这里判断是否重复的标准为用户id等区分度高的属性,如果相等,就属于重复数据。

  测试用例用户实体类取《一步步搭建 Spring Boot maven 框架的工程》中的User,再添加一个业务需求细节:如果list1和list2中的数据重复,则客户姓名以list2为准。

使用Map去重

public static void main(String[] args) {
 
        List<User> list1 = new ArrayList<>();
        User user01 = new User();
        user01.setId(1L);
        user01.setName("Bell");
        list1.add(user01);
        User user02 = new User();
        user02.setId(2L);
        user02.setName("Jack");
        list1.add(user02);
 
        List<User> list2 = new ArrayList<>();
        User user03 = new User();
        user03.setId(2L);
        user03.setName("Tom");
        list2.add(user03);
        User user04 = new User();
        user04.setId(3L);
        user04.setName("Tao");
        list2.add(user04);
 
        Map<Long, User> target = new HashMap<Long, User>();
        if (CollectionUtils.isNotEmpty(list1) && CollectionUtils.isNotEmpty(list2)) {
             //把list1放入Map target中,key取用户id
            for (User tempUser : list1) {
                target.put(tempUser.getId(), tempUser);
            }
            for (User user2 : list2) {
                Long userId = user2.getId();
                if (target.containsKey(userId)) {
                    User temp = target.get(userId);
                    // 用户id重复,以list2中的用户姓名为准
                    temp.setName(user2.getName());
                    target.put(userId, temp);
                } else {
                    target.put(userId, user2);
                }
            }
        }
        List<User> list = new ArrayList<User>(target.values());
 
        System.out.println("对象数据类型的list合并并且去重结果====>:" + list);
}
 

使用Set集合(LinkedHashSet/TreeSet)特性去重

  LinkedHashSet是删除一个List中重复数据的最佳方法,强烈推荐。在去重的过程中,LinkedHashSet在内部完成两件事:

  • 删除重复数据;
  • 保持数据添加的顺序。
    /**
     * 基础数据类型的list合并并且去重,业务场景比较简单
     */
    private static void method2() {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(5);
        list1.add(5);

        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(7);
        list2.add(8);
        list2.add(9);
        list2.add(9);
        // 元素合并到 list1 中
        list1.addAll(list2);
        // 去重
        List<Integer> listAll = new ArrayList<>(new LinkedHashSet<>(list1));
        System.out.println("方法二:使用LinkedHashSet去重的结果====> " + listAll);
    }

  当然,我们还可以使用TreeSet去重:

    /**
     * 使用TreeSet实现List去重(有序)
     */
    public static void removeDuplicationByTreeSet() {
        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(7);
        list2.add(8);
        list2.add(9);
        list2.add(9);
        TreeSet set = new TreeSet(list2);
        //清空List集合
        list2.clear();
        //把HashSet对象添加至List集合
        list2.addAll(set);
        System.out.println("使用TreeSet实现List去重(有序),结果====> " + list2);
    }

  有兴趣的老铁可以去看看TreeSet源码,了解一下它是如何去重的。

使用 java 8 新特性 stream 去重

  使用steam的distinct()方法返回一个由不同list组成的流,通过对象的equals()方法进行比较。

  /**
     * 使用list.stream().distinct()去重
     */
    private static void method3() {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(5);
        list1.add(5);

        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(7);
        list2.add(8);
        list2.add(9);
        list2.add(9);
        // 并集
        list1.addAll(list2);

        // 去重
        List<Integer> listAllDistinct = list1.stream().distinct().collect(toList());
        System.out.println("---方法三:使用list.stream().distinct()去重的结果====> " + listAllDistinct);

    }

使用Stream的flatMap删除list对象重复数据

    /**
     * 使用Stream将数据list对象合并去重
     */
    private static void method4() {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(5);
        list1.add(5);

        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(7);
        list2.add(8);
        list2.add(9);
        list2.add(9);

        //使用Stream将数据list对象合并去重
        List<Integer> results = Stream.of(list1, list2)
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println("方法四:---使用Stream将list对象合并去重---" + results);
    }

结束语

  更新于2022-10-15。

  那么大家对于这件事都是怎么看的呢?欢迎在文章下方留言讨论,三人行必有我师焉!小编会仔仔细细地看每条评论。

posted @ 2019-10-20 17:15  楼兰胡杨  阅读(25933)  评论(0编辑  收藏  举报