前端遍历list_Java集合三兄弟List,Set,Map你分的清楚吗?

前言 集合作为Java基础知识的核心部分,不论是在面试还是平时工作中都是经常遇见的。当然面对熟悉的List、Set、Map,面试管的提问一般也都不会从简单的问题出发了,今天就来聊下集合中的高级部分,让你对它们的理解更加清楚。

一、List、Map、Set三个接口,存取元素时,各有什么特点?

(1)Set集合的add有一个boolean类型的返回值,当集合中没有某个元素时,则可以成功加入该 元素,返回结果为true;当集合中存在与某个元素equals方法相等 的元素时,则无法加入该元素, 取元素时只能用Iterator接口取得所有元素,在逐一遍历各个元素;

(2)List表示有先后顺序的集合,调用add()方法,指定当前对象在集合中的存放位置;一个对象可 以被反复存进集合中;每调用一次add()方法,该对象就会被插入集合中一次,其实,并不是把对 象本身存进了集合中,而是在集合中使用一个索引变量指向了该对象,当一个对象被add多次时, 即有多个索引指向了这个对象。List去元素时可以使用Iterator取出所有元素,在逐一遍历,还可 以使用get(int index)获取指定下表的元素;

(3)Map是双列元素的集合,调用put(key,value),要存储一对key/value,不能存储重复的key, 这个是根据eauals来判断;取元素时用get(key)来获取key所对 应的value,另外还可以获取 全部key,全部value。

二. ArrayList 遍历方式

  • 第 1 种,普通 for 循环随机访问,通过索引值去遍历。

// 随机访问     List list = new ArrayList<>();     int size = list.size();     for (int i = 0; i < size; i++) {         value = list.get(i);     }
  • 第 2 种,通过迭代器遍历。即通过 Iterator 去遍历。

// 迭代器遍历    Iterator iter = list.iterator();    while (iter.hasNext()) {        value = iter.next();    }
  • 第 3 种,增强 for 循环遍历。

 // 增强 for 循环    for (String s : list) {        value = s;    }
  • 第 4 种 forEach + lambda 循环遍历

list.forEach(p -> {                p.hashCode();            });
结论:如果数据量比较少的话貌似四种循环耗时都差不多,但是随着数据量的增长会发现 foreach 的效率是最好的。但是从上面我们会发现一个奇怪的现象,第一次循环的时候forEach遍历的时间是最长的尽管数据量非常少也会这样。但是后面的耗时就正常了。如果放开测试里面的预热代码,每次跑出来的耗时也是正常的。

三、ArrayList和LinkedList的底层实现原理?他们为什么线程不安全?在多线程并发操作下,我们应该用什么替代?

1.ArrayList底层通过数组实现,ArrayList允许按序号索引元素,而插入元素需要对数组进行移位等内存操作,所以索引快插入较慢;(扩容方式)一旦我们实例化了ArrayList 无参构造函数默认数组长度为10。add方法底层如 果增加的元素超过了10个,那么ArrayList底层会生成一个新的数组,长度为原来数组长度的1.5倍+1,然后将原数组内容复制到新数组中,并且后续加的内容都会放到新数组中。当新数组无法容纳增加元素时,重复该过程;

2.LinkedList底层通过双向链表实现,取元素时需要进行前项或后项的遍历,插入元素时只需要记录本项的前后 项即可,所以插入快查询慢;

3.ArrayList和LinkedList底层方法都没有加synchronized关键词,多线程访问时会出现多个线程先后更改数据造成得到的数据是脏数据;多线程并发操作下使用Vector来代替,Vector底层也是数组,但底层方法都加synchronized关键字使线程安全,效率较ArrayList差;

四、HashMap和HashTable有什么区别?其底层实现是什么?CurrentHashMap的锁机制又是如何?如果想将一个Map变为有序的,该如何实现?

1.区别:
(1)HashMap没有实现synchronized线程非安全,HashTable实现了synchronized线程安全;
(2)HashMap允许key和value为null,而HashTable不允许

2.底层原理:数组+链表实现

3.ConcurrentHashMap锁分段技术:HashTable效率低下的原因,是因为所访问HashTable的线程都必须竞争同一把锁,那假如容器中有多把锁,每一把锁用于锁住容器中的一部分数据,那么当多线程访问容器中不同的数据时,线程间就不会存在锁竞争,从而提高并发访问率;ConcurrentHashMap使用的就是锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个数据时,其他段的数据也能被其他线程访问;

4.实现TreeMap

五.ArryList 注意点

谨慎使用 ArrayList 中的 subList 方法

  • ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList. 说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。

Listlist = new ArrayList<>();        list.add("1");        list.add("1");        list.add("2");        ArrayList strings =  (ArrayList)list.subList(0, 1);运行结果:Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList  at com.workit.demo.listener.ArrayListTest.main(ArrayListTest.java:29)
  • 在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、 删除均会产 ConcurrentModificationException 异常。

 Listlist = new ArrayList<>();        list.add("1");        list.add("1");        list.add("2");        List subList =  list.subList(0, 1);        // 对原 List 增加一个值        list.add("10");        subList.add("11"); // 这一行会报 java.util.ConcurrentModificationException
  • 初始化 List 的时候尽量指定它的容量大小。(尽量减少扩容次数)

END最后,针对面试我们也有很多专题资料,让你事半功倍

教你如何写高级的前端简历【附简历导图】

2020-08-14

aceb8b510c6744b8de1a4c7a782d8908.png

电话面试-带你领略高级技巧

2020-02-27

c4f720198bb813376e95203aeaf6e7f2.png

打开职场的钥匙“简历”

2019-11-24

b2d8a01d94d5f04b7f6ac1a66149e907.png
关注我们,更多资料等你来

254d4562bbde3745db7f6dd04a12b19d.png

31e9ca45a9f846af873a0abe46030017.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值