Java List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率

2023-05-16

      Java  List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率

--- List 去重复元素的几种办法

一、概述

        面试的时候,有个常见的问题:“List集合如何去除重复元素”。 常见的回答是:“set集合,for循环对比,stream distinct”,那这些常见去重方法,哪个一个更好,哪一个效率更高呢?

        本文将系统的整理,常见的集中List集合去重方法,使用Junit单元测试,对比效率去重效率。

二、代码实现

        1、准备工作

        构建一个 初始化List ,默认10w个元素,使用 StopWatch 作为计时器, @Before 注解,前置初始化集合元素, @After 注解,记录执行程序时间 , @Test 注解,执行测试工作。

final List<Integer> list = Lists.newArrayList();
// 总元素的个数
int count = 100_000;
// 重复元素
int repat = 5;

private StopWatch stopWatch;

@Before
public void init(){
    for (int i = 0; i < count; i++) {
        list.add(i);
    }
    final ArrayList<Integer> repatList = Lists.newArrayList();
    for (int i = 0; i < repat ; i++) {
        int n = (int)(Math.random()*count);
        repatList.add(n);
    }
    list.addAll(repatList);

    System.out.println("list 初始化完毕 size = "+ list.size());
    System.out.println("重复元素是:"+ repatList);
    System.out.println("开始记录时间 === ");
    stopWatch = StopWatch.createStarted();
}

// === 执行单元测试方法 ...
@Test
public void test() throws Exception{
    
} 


@After
public void after() throws Exception {
    stopWatch.stop();
    System.out.println("测试完毕,实际耗时:" +stopWatch.getTime() +" ,ms");
}

        2、for 循环添加去重,list集合

@Test
public void forAddTest() throws Exception {
    final ArrayList<Integer> destList = Lists.newArrayList();
    for (Integer e : list) {
        if (!destList.contains(e)) {
            destList.add(e);
        }
    }
    System.out.println("forAddTest ,去重后,集合元素个数 :" + destList.size());
}

        2.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[43491, 7220, 42984, 65619, 35564]
开始记录时间 === 
forAddTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:5187 ,ms

Process finished with exit code 0

        3、for 循环添加去重,set 集合

@Test
public void forAddSetTest() throws Exception {
    final LinkedHashSet<Object> set = Sets.newLinkedHashSet();
    for (Integer e : list) {
        if (!set.contains(e)) {
            set.add(e);
        }
    }
    System.out.println("forAddSetTest ,去重后,集合元素个数 :" + set.size());
}

        3.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[18748, 56260, 94869, 65498, 352]
开始记录时间 === 
forAddSetTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:28 ,ms

        4、for 双循环去重,remove去重

@Test
public void forRemoveTest() throws Exception {
    for (int i = 0; i < list.size() - 1; i++) {
        for (int j = list.size() - 1; j > i; j--) {
            if (list.get(j).equals(list.get(i))) {
                list.remove(j);
            }
        }
    }
    System.out.println("forRemoveTest ,去重后,集合元素个数 :" + list.size());
}

        4.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[24090, 85604, 21849, 26039, 34851]
开始记录时间 === 
forRemoveTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:12475 ,ms

Process finished with exit code 0

        5、 for 循环去重复,index索引去重

@Test
public void forIndexRemoveTest() throws Exception {
    List<Integer> list2 = new ArrayList(list);
    for (Integer element : list2) {
        if (list.indexOf(element) != list.lastIndexOf(element)) {
            list.remove(list.lastIndexOf(element));
        }
    }
    System.out.println("forIndexRemoveTest ,去重后,集合元素个数 :" + list.size());
}

        5.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[24097, 8550, 83199, 66946, 83527]
开始记录时间 === 
forIndexRemoveTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:11679 ,ms

        6、转换到set集合中去重

@Test
public void toSetTest() throws Exception {
    final HashSet<Integer> set = Sets.newHashSet(list);
    final ArrayList<Integer> integers = Lists.newArrayList(set);
    System.out.println("toSetTest ,去重后,集合元素个数 :" + integers.size());
}

        6.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[97016, 15751, 98344, 48053, 70403]
开始记录时间 === 
toSetTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:29 ,ms

        7、使用Stream流,toSet集合中 去重

@Test
public void streamToSetTest() throws Exception {
    final List<Integer> collect = list.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());
    System.out.println("streamToSetTest ,去重后,集合元素个数 :" + collect.size());
}

        7.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[14265, 81375, 57191, 21029, 77598]
开始记录时间 === 
streamToSetTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:66 ,ms

        8、使用 Stream流,Distinct 中进行去重

@Test
public void streamDistinctTest() throws Exception {
    final List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
    System.out.println("streamDistinctTest ,去重后,集合元素个数 :" + collect.size());
}

        8.1、输出结果:

list 初始化完毕 size = 100005
重复元素是:[97197, 34832, 14705, 57613, 14578]
开始记录时间 === 
streamDistinctTest ,去重后,集合元素个数 :100000
测试完毕,实际耗时:61 ,ms

三、总结

        1、从整体执行效率上看: Stream Distinct 方法, 效率最高,其次就是转换为 set

for循环对比,是效率最低的,不可取!

stream Distinct > toSet > streamToSet > forAdd > forIndexRemove > forRemove

 

 

        2、注意:forSetTest 比 forAddSetTest 效率低,原因是: list.contains和 set.contains方法 ,底层实现不同,list.contains 方法是逐个遍历判断,效率低下。

 

 

        2.1、注意点:若是普通对象去重,则需要 手动重写equals和hashCode方法,否则会出现去重无效的情况!

若是List<User> 对象去重,重写 User对象的equals和hashCode方法

        3、面试的时候建议回答: JDK8之前放到set集合中JDK8及以后,使用 Stream distinct 方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率 的相关文章

  • 内存地址的应用

    学习python时真正了解了内存地址 cpu中的数据分类 cpu中的数据分为两类 xff1a 数据和指令 数据 xff1a 由指令产生的结果 指令 xff1a 键盘 鼠标等电脑输入设备操作以及人为对主机输入设备进行的目的性操作 值得注意的是
  • World插入图片显示不全

    在文档中直接插入图片 xff0c 显示不全 xff0c 具体的说是只能看到图片底部部分 给出两种办法解决 1 局部修改 把光标位置置于图片的末尾 xff0c 然后点击鼠标右键 xff0c 选择 段落 选项进入 段落 文本框 xff0c 选择
  • 快速消除Word文档中空格

    消除Word文档中的空格 0 待处理文档 1 选择文档的替换功能 2 选择 特殊格式 中的 段落标记p 3 设置成对应格式 4 选择全部替换 xff0c 效果如下 问题分析 xff1a 可以看出执行上述操作一次后 xff0c 相当于是扫描了
  • CCF推荐国际学术会议和期刊目录2019年

    链接 xff1a 全目录下载地址
  • 2022教资押题

    1 试题类型 2 具体文件夹 3 百度网盘链接 xff1a 链接 xff1a https pan baidu com s 17ZlLeE2E8Rzz7ELHptE8Fg 提取码 xff1a 9vky
  • 强化学习Q-learning入门教学

    1 问题描述 2 图形化展示 3 reward矩阵构建 4 Q表构建 这里需要说明的是Q表的转移规则原本是 xff1a 本例中为了方便介绍 xff0c 将 值设为1了 原文讲解的通俗易懂 xff0c 有兴趣的可以看一下 出处 xff1a h
  • 英文文献代码查找

    原文链接 xff1a https blog csdn net weixin 45656790 article details 109271019
  • Word中插入集合和元素的包含符号

    1 比较简单 xff0c 是元素和集合的包含关系 查找 xff1a word gt 插入 gt 符号栏下拉 xff0c 选择基础数学 2 集合间的包含关系 四个数字 xff0c 代表一个 输入文档中的指定位置 xff0c 选中数字以后 xf
  • 微信PC端聊天界面表情包无法显示

    我试成功的一个办法 xff0c 分享一下 具体步骤 xff1a 1 找到微信聊天界面的设置选项 xff0c 如图 2 进入微信文件保存位置 3 进入WeChat Files All Users config目录 4 删除config dat
  • MathType 提示需要一个新版本的MT Extra(True Type)字体

    1 打开C Windows Fonts文件夹 xff0c 若里面有MT Extra TrueType 字体或其快捷方式 xff0c 则将其删除 2 找到MathType安装目录下C Program Files x86 MathType Fo
  • Word快捷键设置上下标;Word取消表格虚线;Word查找数学符号

    问题1 快捷键设置上下角标 这个在论文写作时比较常用 xff0c 本人也是最近在写大论文 xff0c 遇到了这个情况 Word和Visio中 xff0c 都可以使用 步骤 xff1a 选中即将成为上下标的内容 xff0c 上标快捷键 xff
  • xcode中xib使用之轻松学习

    1 创建xib文件 在工程目录中New Files xff0c 选择user interface类型中的empty创建一个空的interface builder document文件 文件名没有强制的要求 xff0c 最好使用 前缀 xff
  • 用Opencv打造一台自动视觉目标跟踪系统

    平移 倾斜伺服装置 xff0c 帮助摄像机使用视觉自动跟踪颜色对象 简介 现在我们将使用我们的设备帮助相机自动跟踪颜色对象 xff0c 如下所示 xff1a OpenCV可免费用于学术和商业用途 它具有C 43 43 xff0c C xff
  • error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools"【转载+修改】

    error Microsoft Visual C 43 43 14 0 is required Get it with Microsoft Visual C 43 43 Build Tools http landinghub visuals
  • 如何使用OpenCV实现多张图像拼接

    先来看看OpenCV官方的例子得到效果是非常的好 xff0c 输入的images如下 xff1a 效果 xff1a Stitcher类与detail命名空间 OpenCV提供了高级别的函数封装在Stitcher类中 xff0c 使用很方便
  • 如何使用OpenCV对物体进行搜索检测与识别

    在本教程中 xff0c 我们将了解对象检测中称为 选择性搜索 的重要概念 我们还将用C 43 43 和Python共享OpenCV代码 物体检测与物体识别 对象识别算法识别图像中存在哪些对象 它将整个图像作为输入 xff0c 并输出该图像中
  • 一种基于深度学习的方法来检测摩托车头盔的使用

    背景 据统计使用摩托车头盔可以将道路交通事故中摩托车驾驶员致命伤害的可能性降低42 xff05 xff0c 尽管如此 xff0c 遵守摩托车头盔还是较少 xff0c 尤其是在发展中国家 xff0c 为了有效开展针对性的头盔使用运动 xff0
  • 偏振光相机1——偏振光

    光的电磁波属性 光是一种电磁波 xff0c 这个概念大家应该不陌生 既然是电磁波 xff0c 那我们从电磁波的特性上来看它有哪些属性 用图1中的交变电磁场来描述光的特性 xff0c 电场和磁场在空间中相互垂直 xff0c 它们同时与光的传播
  • 偏振光相机2——索尼大法

    Stokes参量 在上一篇 偏振光相机 偏振光 中 xff0c 我们知道偏振光有线性偏振光 椭圆偏振光 圆偏光 那么如何定量的描述偏振光呢 xff1f Stokes矢量是一种广泛用来描述偏振光属性的方法 图1 不同类型的偏振光 线性偏振光和
  • 偏振光相机3——偏振应用

    在之前的2篇中 xff0c 介绍了偏振光的基本概念和基于SONY最新CMOS偏振传感器芯片的相机 在本篇中 xff0c 我们来看看偏振相机的一些应用 偏振相机的应用离不开偏振光 xff0c 那么先看看如何得到偏振光信息 如何获取偏光 在 偏

随机推荐