0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

不好意思,list.contain 去重该换换了!

jf_ro2CN3Fa 来源:csdn 2023-09-14 15:50 次阅读


前言

最近又是一轮代码review , 发现了一些实现去重的代码,在使用 lsit.contain ......

如:

e47d2246-52c5-11ee-a25d-92fbcf53809c.png

我沉思,是不是其实很多初学者也存在这种去重使用问题?

所以我选择把这个事情整出来,分享一下。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

正文

首先是造出一个 List 模拟数据,一共2W条,里面有一半数据1W条是重复的:

publicstaticListgetTestList(){
Listlist=newArrayList<>();
for(inti=1;i<= 10000;i++){
list.add(String.valueOf(i));
}
for(inti=10000;i>=1;i--){
list.add(String.valueOf(i));
}
returnlist;
}

先看看 我们用contain 去重的 代码:

/**
*使用list.contain去重
*
*@paramtestList
*/
privatestaticvoiduseContain2Distinct(ListtestList){
System.out.println("contains 开始去重,条数:"+testList.size());
ListtestListDistinctResult=newArrayList<>();
for(Stringstr:testList){
if(!testListDistinctResult.contains(str)){
testListDistinctResult.add(str);
}
}
System.out.println("contains 去重完毕,条数:"+testListDistinctResult.size());
}

我们调用一下看看耗时:

publicstaticvoidmain(String[]args){
ListtestList=getTestList();
StopWatchstopWatch=newStopWatch();
stopWatch.start();
useContainDistinct(testList);
stopWatch.stop();
System.out.println("去重最终耗时"+stopWatch.getTotalTimeMillis());
}

耗时:

e4e0cf62-52c5-11ee-a25d-92fbcf53809c.png

评价:list.contain 的效率,我的建议是,知道就行,别用。

众所周知Set 不存在 重复数据, 所以我们来看看 使用HashSet去重的性能:

ps:这里是采取使用 set的add 方法做去重

/**
*使用set去重
*
*@paramtestList
*/
privatestaticvoiduseSetDistinct(ListtestList){
System.out.println("HashSet.add 开始去重,条数:"+testList.size());
ListtestListDistinctResult=newArrayList<>(newHashSet(testList));
System.out.println("HashSet.add 去重完毕,条数:"+testListDistinctResult.size());
}

我们调用一下看看耗时:

publicstaticvoidmain(String[]args){
ListtestList=getTestList();
StopWatchstopWatch=newStopWatch();
stopWatch.start();
useSetDistinct(testList);
stopWatch.stop();
System.out.println("去重最终耗时"+stopWatch.getTotalTimeMillis());
}

耗时:

e4fe2a76-52c5-11ee-a25d-92fbcf53809c.png

评价:HashSet 的效率,我的建议是,推荐

为什么耗时 差距这么大?

不多说,我们看源码:

list.contains(o)

e52a707c-52c5-11ee-a25d-92fbcf53809c.png

可以看到里面用到了 index(o) :

e55c2b6c-52c5-11ee-a25d-92fbcf53809c.png

时间复杂度 :O(n) ,n: 元素个数

那么我们看看 set.add(o) 是怎么样的 :

e592714a-52c5-11ee-a25d-92fbcf53809c.png

map的add , 老生常谈就不谈了,hash完 直接塞到某个位置, 时间复杂度 : O(1)

所以 O(n)O(1) 谁快 谁慢 ?显然。

ps:顺嘴说下 hashset的 contain

e5f8344e-52c5-11ee-a25d-92fbcf53809c.png

时间复杂度也是 :O(1)

e6436216-52c5-11ee-a25d-92fbcf53809c.png

那么我们最后再看看别的去重:

双for循环 ,remove去重

/**
*使用双for循环去重
*@paramtestList
*/
privatestaticvoiduse2ForDistinct(ListtestList){
System.out.println("list 双循环开始去重,条数:"+testList.size());
for(inti=0;i< testList.size(); i++) {
        for(intj=i+1;j< testList.size(); j++) {
            if(testList.get(i).equals(testList.get(j))){
testList.remove(j);
}
}
}
System.out.println("list 双循环去重完毕,条数:"+testList.size());
}
publicstaticvoidmain(String[]args){
ListtestList=getTestList();
StopWatchstopWatch=newStopWatch();
stopWatch.start();
use2ForDistinct(testList);
stopWatch.stop();
System.out.println("去重最终耗时"+stopWatch.getTotalTimeMillis());
}

耗时:

e67cb2e6-52c5-11ee-a25d-92fbcf53809c.png

评价:知道就行,图个乐,别用,贼慢,而且代码看起来乱:。

stream的distinct去重:

/**
*使用Stream去重
*
*@paramtestList
*/
privatestaticvoiduseStreamDistinct(ListtestList){
System.out.println("stream 开始去重,条数:"+testList.size());
ListtestListDistinctResult=testList.stream().distinct().collect(Collectors.toList());
System.out.println("stream 去重完毕,条数:"+testListDistinctResult.size());
}
publicstaticvoidmain(String[]args){
ListtestList=getTestList();
StopWatchstopWatch=newStopWatch();
stopWatch.start();
useStreamDistinct(testList);
stopWatch.stop();
System.out.println("去重最终耗时"+stopWatch.getTotalTimeMillis());
}

耗时:

e69edfb0-52c5-11ee-a25d-92fbcf53809c.png

评价:还不错,主要是代码也蛮简洁,有一点点动心。

好了,该篇就到这。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6514

    浏览量

    87609
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66812
  • spring
    +关注

    关注

    0

    文章

    333

    浏览量

    14161

原文标题:不好意思,list.contain 去重该换换了!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    “太厉害了,一定要学会它!”电子工程师未来“金主”在这!

    现在不聊点物联网沾边的事情都不好意思说自己电子工程师。所以,ARM mbed OS来了。
    发表于 08-04 09:56 2820次阅读

    新来的,冒个泡!

    今天才发现这个地方,不好意思,来迟了!
    发表于 08-22 18:11

    eg8010产生spwm波的非常好用!!!

    不好意思刚才上传了一个要e币的
    发表于 09-01 19:44

    我知道大过年的麻烦个位大哥大姐的不好,不过问题搞不.....

    `大过年的小弟在这给各位大哥大姐拜年了,祝各位身体健康,财源广进大过年的来麻烦人实在不好意思,不过有些问题憋着不知道实在难受,望好心人解释下1,这个无线供电的电路图里,Q2的作用是什么,Q1导通他才
    发表于 02-10 21:51

    不好意思,我删了

    [ 本帖最后由 lanyue119 于 2013-3-20 09:45 编辑 ]\n\n不好意思,我删了
    发表于 03-06 18:48

    labview模拟电压检测显示系统

    不好意思,新人发帖,忘了加附件。
    发表于 06-16 17:17

    LM386简单运放***

    `简单的***设计LM386.都不好意思拿出来了,但为了....`
    发表于 06-27 12:05

    零基础三天三十元做出智能车

    不好意思,有点残缺看看吧
    发表于 07-17 23:18

    网上买了快开发板,分享一下资料

    实在不好意思,限制上传单个文件最大20M,我只能分开来传了,我弄了个网盘(你们也可以注册的,地址http://www.7958.com/r_164028.html)http://937358885.7958.com
    发表于 09-28 00:53

    开关电源仿真

    不好意思,你的问题我不会,但我想问你个问题,你仿真过开关电源电路吗?
    发表于 06-07 09:05

    LabVIEW辞职信---搞笑界面(由于上次缺少VI,这次修改后重新发)

    不好意思,上次失误,导致发出去的文件丢失VI,今天重发。
    发表于 07-30 16:38

    怎样判断汽车电瓶该换了

    `  怎样判断汽车电瓶该换了?`
    发表于 11-07 17:13

    proteus中英文对照

    一些常用的proteus中英文对照,希望有帮助,内容不多不好意思
    发表于 11-09 14:44 0次下载

    美图m8怎么样 私人美颜师

    今年最火的时尚单品是什么?如果你的回答是星辰版的YSL,不好意思,你可能已经走到时尚圈的外环了。
    的头像 发表于 08-29 14:30 4052次阅读

    Clock Gating的特点、原理和初步实现

    当下这社会,没有几万个Clock Gating,出门都不好意思和别人打招呼!
    的头像 发表于 07-17 16:50 2652次阅读
    Clock Gating的特点、原理和初步实现