当前位置: 首页 > 编程日记 > 正文

java遍历的优化

说明:这是在面试中面试官出的题。虽然是常见的优化问题,但这种经验的确很有用。感慨之余,分享出来,以此共勉。

场景:现有List<PersonA>,List<PersonB>,PersonA 的属性是 String类型的身份证号,int型age;PersonB 的属性是 String类型的身份证号,int型sex;两个集合中的身份证号有相同的;

需求:查找身份证号相同的人的性别。

常见的思路是:

 1 @Data
 2 public class PersonA {
 3     private String card;
 4     private int age;
 5 
 6     public PersonA(String card, int age) {
 7         this.card = card;
 8         this.age = age;
 9     }
10 }
11 ----------------------------------------------
12 @Data
13 public class PersonB {
14     private String card;
15     private int sex;
16 
17     public PersonB(String card, int sex) {
18         this.card = card;
19         this.sex = sex;
20     }
21 }

public class TestForFor {private List<PersonA> pa;private List<PersonB> pb;@Beforepublic void before(){pa = new ArrayList<>();for (int i = 0; i < 10000; i++) {pa.add(new PersonA(UUID.randomUUID().toString(),20));}pa.add(new PersonA("abcd111",10));pa.add(new PersonA("abcd112",10));pa.add(new PersonA("abcd113",10));pa.add(new PersonA("abcd114",10));pa.add(new PersonA("abcd115",10));pa.add(new PersonA("abcd116",10));pb = new ArrayList<>();for (int i = 0; i < 10000; i++) {pb.add(new PersonB(UUID.randomUUID().toString(),Math.random() >= 0.5 ? 1 : 0));}pb.add(new PersonB("abcd111",1));pb.add(new PersonB("abcd112",1));pb.add(new PersonB("abcd113",1));pb.add(new PersonB("abcd114",1));pb.add(new PersonB("abcd115",1));pb.add(new PersonB("abcd116",1));}@Testpublic void testFor(){out.println("start search");for (PersonA a : pa) {for (PersonB b : pb) {if (a.getCard().equals(b.getCard())){out.println(b.getSex()==1?"男":"女");}}}}
}

结果。。。花费三秒多的时间。这还只是一万条数据

现在换一种思路,直接贴代码

 1  private List<PersonA> pa;
 2     private List<PersonB> pb;
 3     private Map<String,Object> map;
 4     @Before
 5     public void before(){
 6         out.println("start before");
 7         pa = new ArrayList<>();
 8         for (int i = 0; i < 10000; i++) {
 9             pa.add(new PersonA(UUID.randomUUID().toString(),20));
10         }
11         pa.add(new PersonA("abcd111",10));
12         pa.add(new PersonA("abcd112",10));
13         pa.add(new PersonA("abcd113",10));
14         pa.add(new PersonA("abcd114",10));
15         pa.add(new PersonA("abcd115",10));
16         pa.add(new PersonA("abcd116",10));
17 
18 
19         pb = new ArrayList<>();
20         for (int i = 0; i < 10000; i++) {
21             pb.add(new PersonB(UUID.randomUUID().toString(),Math.random() >= 0.5 ? 1 : 0));
22         }
23         pb.add(new PersonB("abcd111",1));
24         pb.add(new PersonB("abcd112",1));
25         pb.add(new PersonB("abcd113",1));
26         pb.add(new PersonB("abcd114",1));
27         pb.add(new PersonB("abcd115",1));
28         pb.add(new PersonB("abcd116",1));
29         map = new HashMap<>();
30         for ( PersonB pbb : pb ) {
31             map.put(pbb.getCard(),pbb.getSex());
32         }
33     }
34     @Test
35     public void testFor(){
36         out.println("start search");
37         for (PersonA a : pa) {
38             if (map.containsKey(a.getCard())){
39                 out.print(a.getAge()+" ");
40                 out.println((int)map.get(a.getCard())==1?"男":"女");
41             }
42             //out.println(map.get(a.getCard())==null?"空":map.get(a.getCard()));
43             //out.println((int)map.get(a.getCard())==1?"男":"女");
44         }
45     }

可以看出,查找的效率明显提升。

这里面的重点,第29行我用map重新填写了pb的数据[我的本地的sql坏了,所以用伪数据库的方式模仿,感兴趣也可以从数据库里试试],

为什么用map填完了后速度会这么快?

原因很简单。因为ArrayList的底层是数组实现的,若要查找必定是从索引0开始一个个的进行比对;而HashMap则不同,

HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度依然为O(1),因为最新的Entry会插入链表头部,仅需要简单改变引用链即可,而对于查找操作来讲,此时就需要遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。

关于以上加粗内容取自博客

我在面试时只想到了hash,面试官提醒我用hashmap,恍然大悟。


时隔数月,回来归纳下这个问题。2018/9/13


其实这个问题可以抽象为:两个数组求交集,这里简要说下思路。

使用 treeset装载第一个数组,遍历第二个数组,if(!contains数组二中的值),add到一个新list中,最后这个list存的就是交集

原创分享,转载标注。

转载于:https://www.cnblogs.com/find-the-right-direction/p/8506289.html

相关文章:

深入浅出Pytorch:02 PyTorch基础知识

深入浅出Pytorch 02 PyTorch基础知识 内容属性&#xff1a;深度学习&#xff08;实践&#xff09;专题航路开辟者&#xff1a;李嘉骐、牛志康、刘洋、陈安东领航员&#xff1a;叶志雄航海士&#xff1a;李嘉骐、牛志康、刘洋、陈安东开源内容&#xff1a;https://github.com/…

java for 两个条件_for循环条件里定义2个变量为什么会报错

public class HelloWorld {//完成 main 方法public static void main(String[] args) {int scores[]{89,-23,64,91,119,52,73};HelloWorld hellonew HelloWorld();hello.sortScore(scores);}//定义方法完成成绩排序并输出前三名的功能public void sortScore(int[] scores){Arra…

Qt4在linux下的安装

1、下载SDK ftp://ftp.informatik.hu-berlin.de/pub/Mirrors/ftp.troll.no/QT/qtsdk/qt-sdk-linux-x86-opensource-2010.05.1.bin 2、修改文件权限 想要安装SDK&#xff0c;需要拥有对其读写和执行的权限。可以通过【右键】->【属性】->【权限】进行设置。 也可以通过命…

高性能千万级定时任务管理服务forsun使用详解

Forsun高性能高精度定时服务&#xff0c;轻松管理千万级定时任务。项目地址&#xff1a; https://github.com/snower/forsun 使用 linux 系统定时器提供精确到秒级的定时调度&#xff0c;长时间运行保证无误差。支持本地内存存储和 redis 持久化存储&#xff0c;使用 redis 可轻…

谢文睿:西瓜书 + 南瓜书 吃瓜系列 11. 贝叶斯分类器

吃瓜教程——西瓜书南瓜书 Datawhale南瓜书是经典机器学习教材《机器学习》&#xff08;西瓜书&#xff09;的公式推导解析指南&#xff0c;旨在让在学习西瓜书的过程中&#xff0c;再也没有难推的公式&#xff0c;学好机器学习。 内容属性&#xff1a;机器学习&#xff08;理…

java 上传的图片大小为0_JAVA技术:上传图片的缩放处理

图片上传到后&#xff0c;会根据情况将图片缩小成一个图标&#xff0c;我们可以利用java强大的图形处理功能&#xff0c;对上传的图片进行缩放处理。下面的程序使用jdk1.4中最新的ImageIO对图片进行读写。使用AffineTransform对图片进行缩放。import java.io.File&#xff1b;i…

信息安全推荐书籍

本页列出了我发现的与计算机安全&#xff0c;数字取证&#xff0c;事件响应&#xff0c;恶意软件分析和逆向工程以及其他相关主题学习主题高度相关和有用的书籍。这些书从介绍性文本到高级研究作品。尽管这些书中的一些看起来有点过时&#xff0c;但所包含的信息对今天学习的人…

paip.odbc DSN的存储与读取

paip.odbc DSN的存储与读取 作者Attilax &#xff0c; EMAIL:1466519819qq.com 来源&#xff1a;attilax的专栏 地址&#xff1a;http://blog.csdn.net/attilax 1.列出系统级ODBC列表 ---------------------- [HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\ODBC Data So…

【青少年编程】【三级】计算平均分

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100&#xff0c;小马老…

java 判断是否为邮箱_Java判断邮箱是否存在 有返回值

public static boolean checkEmail(String email) {if (!email.matches("[\\w\\.\\-]([\\w\\-]\\.)[\\w\\-]")) {return false;}String log "";String host "";String hostName email.split("")[1];// 去掉后面的System.out.printl…

Android Handler介绍

本文转自:http://www.cnblogs.com/keyindex/articles/1822463.html前言 学习android一段时间了&#xff0c;为了进一步了解android的应用是如何设计开发的&#xff0c;决定详细研究几个开源的android应用。从一些开源应用中吸收点东西&#xff0c;一边进行量的积累&#xff0c;…

阿里巴巴一年投三家AR公司,AR购物或是最终目标

阿里巴巴再投资AR公司&#xff0c;一年连续投资超2.2亿美元&#xff0c;它到底想要做什么&#xff1f; 最近&#xff0c;以色列AR眼镜厂商Lumus获得来自阿里巴巴的600万美元的投资。此前&#xff0c;镁客网报道过这家公司在去年12月份获得由广达电脑、HTC和盛大集团投资的300万…

青少年编程竞赛交流群周报(第035周)

2021年10月24日&#xff08;周日&#xff09;晚20:00我们在青少年编程竞赛交流群开展了第三十五期直播活动。 一、直播内容 我们直播活动的主要内容如下&#xff1a; 讲解了上次测试中小朋友们做错的题目 Scratch青少年编程能力等级测试模拟题&#xff08;四级&#xff09;。…

java 接口工程_Java工程师(15)抽象类与接口

抽象类思考下面程序潜在的问题交通工具中定义了4个方法&#xff0c;其中行驶方法内部会依次调用启动、加速、停止方法。由于不同的交通工具&#xff0c;启动的方式差异很大&#xff0c;所以交通工具类中并不实现该方法&#xff0c;而是将其交给子类实现。上述代码的问题&#x…

为什么必须是final的呢?

一个谜团 如果你用过类似guava这种“伪函数式编程”风格的library的话&#xff0c;那下面这种风格的代码对你来说应该不陌生&#xff1a; 1 2 3 4 5 6 7 8 9public void tryUsingGuava() {final int expectedLength 4;Iterables.filter(Lists.newArrayList("123", &…

java mvc view_对Springmvc view层的理解

MVC框架可以把应用清晰明了地分为三个部分&#xff1a;Model层–数据层&#xff0c;View层–视图层&#xff0c;Controller–逻辑层&#xff0c;Model层负责整合数据&#xff0c;View层负责页面渲染&#xff0c;Controller层负责实现业务逻辑。我在这里简单说一下我对MVC框架中…

【优秀作业】粒子群算法

粒子群优化算法 一、概述 粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;的思想来源于对鸟捕食行为的模仿&#xff0c;最初&#xff0c;Reynolds.Heppner 等科学家研究的是鸟类飞行的美学和那些能使鸟群同时突然改变方向&#xff0c;分散…

面向对象进阶2 组合

2019独角兽企业重金招聘Python工程师标准>>> 一&#xff1a;命名空间 class Person:Country 中国人 # 静态变量print(Person.Country) alex Person() # 创建了一个空的命名空间 alex.name alex # 对象 alex.Country 泰国人 egon Person() egon.name ego…

Android基础知识之Manifest文件的组织结构

原文&#xff1a;http://android.eoe.cn/topic/android_sdk 是AndroidManifest.xml文件中的根标签&#xff0c;她必须包含一个标签和指定的xmlns:android、 package两个属性。 属性&#xff1a; xmlns:android定义了Android的命名空间。这个属性一般可以设置为&#xff1a;&quo…

java类的注释模板_IDEA添加Java类注释模版的方法

本文介绍了idea添加java类注释模版的方法&#xff0c;分享给大家&#xff0c;具体如下&#xff1a;idea版本&#xff1a;intellij idea 2017.2.5 x64eclipse能在类上方输入/**,回车添加类注释模版&#xff0c;但idea没有默认添加这个功能&#xff0c;需要做一些设置。下面介绍三…

POJ 2586 Y2K Accounting Bug(贪心)

题目连接&#xff1a;http://poj.org/problem?id2586 题意&#xff1a;某公司要统计全年盈利状况&#xff0c;对于每一个月来说&#xff0c;如果盈利则盈利S&#xff0c;如果亏空则亏空D。公司每五个月进行一次统计&#xff0c;全年共统计8次(1-5、2-6、3-7、4-8、5-9、6-10、…

【组队学习】10月份微信图文索引

10月份微信图文索引 一、组队学习相关 周报&#xff1a; Datawhale组队学习周报&#xff08;第036周&#xff09;Datawhale组队学习周报&#xff08;第035周&#xff09;Datawhale组队学习周报&#xff08;第034周&#xff09;Datawhale组队学习周报&#xff08;第033周&…

java spring scope_如何在Spring中自定义scope的方法示例

大家对于 Spring 的 scope 应该都不会默认。所谓 scope&#xff0c;字面理解就是“作用域”、“范围”&#xff0c;如果一个 bean 的 scope 配置为 singleton&#xff0c;则从容器中获取 bean 返回的对象都是相同的&#xff1b;如果 scope 配置为prototype&#xff0c;则每次返…

学习ExtJS4 常用控件

ExtJS组件配置方式介绍 1.使用逗号分隔参数列表配置组件 首先来看一个简单的逗号分隔参数列表的例子。这个例子非常简单&#xff0c;它用来显示信息提示框。 2.使用Json对象配置组件 接下来看一个使用Json对象配置组件的例子&#xff0c;很多地方习惯性称之为配…

青少年编程竞赛交流群周报(第036周)

2021年10月31日&#xff08;周日&#xff09;晚20:00我们在青少年编程竞赛交流群开展了第三十六期直播活动。 一、直播内容 我们直播活动的主要内容如下&#xff1a; 讲解了上次测试中小朋友们做错的题目 Scratch青少年编程能力等级测试模拟题&#xff08;四级&#xff09;。…

中国电信打造“三朵云”战略 助力互联网+医疗发展

随着云计算、大数据的快速发展&#xff0c;全行业上云成为一个趋势&#xff0c;在健康医疗这个领域&#xff0c;应大势之趋&#xff0c;纷纷构建医疗云。近日&#xff0c;中国电信医疗云专区北京节点发布会在京顺利召开&#xff0c;会后北京电信副总经理项煌妹接受了中国IDC圈记…

python 数据类笔试题_一道 Python 类的笔试题详解

r {}class C(object):def __init__(self, a, b):self.a aself.b bif b a:orig super(C, cls)r[cls.instance] 1a C(1, a)b C(1, a)c C(1, b)l [a, b, c]for i in l:if i not in r:r[i] 1else:r[i] 1assert r[a] 2assert r[b] 2assert r[c] 1原题目要求如下&…

【优秀作业】粒子群算法(Python)

粒子群优化算法 一、概述 粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;的思想来源于对鸟捕食行为的模仿&#xff0c;最初&#xff0c;Reynolds.Heppner 等科学家研究的是鸟类飞行的美学和那些能使鸟群同时突然改变方向&#xff0c;分散…

警惕企业中的五种虚假执行力

第一种虚假执行力&#xff1a;无条件服从——只强调员工“服从”&#xff0c;不强调员工的智慧 很多人讲执行力&#xff0c;很喜欢强调员工的无条件服从。这种观念是OEM(代工生产)制造业时代的产物。实际上这是一种基于“规模制造”的虚假执行力&#xff0c;其本质是把人当成了…