关注小程序 找一找教程网-随时随地学编程

Java教程

关于集合框架List,你所不知道的知识!

前言

相信很多同学们都了解集合框架List,但是你们真的掌握List了吗?是不是对于某些概念还是有些模糊呢?那不妨看看我的这篇文章,或许你会有所收获!

解析ArrayList

答:首先,我们来讲解的是ArrayList集合,它是我们用得非常非常多的一个集合。ArrayList底层是一个数组,ArrayList中有扩容的概念,正因为它可以扩容,所以它能够实现“动态”增长。ArrayList是线程不安全的。(注:有兴趣的同学可以多看看JDK源码,多看源码对你的编程能力会有很大的提升)

解析Vector

答:Vector是JDK1.2的类,是一个比较老的集合类,现在几乎很少用到。Vector底层也是数组,与ArrayList最大的区别就是线程安全。

解析LinkedList

答:LinkedList底层是双向链表,是线程不安全的。

Vector和ArrayList、LinkedList联系与区别是什么?分别的使用场景是什么?

答: ArrayList:底层是数组实现,线程不安全,查询和修改非常快,但是增加和删除慢。

LinkedList: 底层是双向链表,线程不安全,查询和修改速度慢,但是增加和删除速度快。

Vector: 底层是数组实现,线程安全的,操作的时候使用synchronized进行加锁。

使用场景: Vector已经很少用了,增加和删除场景多则用LinkedList,查询和修改多则用ArrayList。

如果让ArrayList保证线程安全,应该怎么做?

答:关于该问题介绍三种方式:

第一种:自己写一个包装类进行加锁操作,一般根据你的业务自定义。

第二种:使用List< String> list = Collections.synchronizedList(new ArrayList<>());来创建的ArrayList是线程安全的。从JDK源码中可以看到该方法使用synchronized进行加锁操作。

第三种方式:用CopyOnWriteArrayList<>();它是java.util.concurrent包下的类。该方法使用ReentrantLock加锁。

CopyOnWriteArrayList与Collections.synchronizedList实现线程安全有什么区别? 使用场景是怎样的?

答: CopyOnWriteArrayList:执行修改操作时,会拷贝一份新的数组进行操作(add、set、remove等),代价十分昂贵,在执行完修改后将原来集合指向新的集合来完成修改操作,源码里面用ReentrantLock可重入锁来保证不会有多个线程同时拷贝一份数组。

使用场景:适用读操作远远大于写操作的场景中使用,读的时候是不需要加锁的,直接获取,删除和增加是需要加锁的。

Collections.synchronizedList:线程安全的原因是因为它几乎在每个方法中都使用了synchronized同步锁机制。

场景:写操作性能比CopyOnWriteArrayList好,读操作性能并不如CopyOnWriteArrayList。

CopyOnWriteArrayList有什么缺点?

答:内存占用问题,写时复制机制,内存里会同时驻扎两个对象的内存。

ArrayList的扩容机制

答:JDK1.7之前ArrayList默认大小是10,JDk1.7之后是0。若未指定集合容量,则默认是0,若已经指定大小则集合大小为指定的大小。当集合第一次添加元素的时候,集合大小扩容为10,当ArrayList的元素个数大于其容量,扩容的大小= 原始大小+原始大小/2。举例:当你添加第一个元素,集合大小扩容为10;当你添加第11个元素时,集合大小扩容为15。

结语

关于集合框架List,以上内容是我所知道的,欢迎大家继续补充。具体它们有哪些方法,建议去翻看JDK源码。当然,仅仅会概念是不行的,想要真正掌握就要在实际项目中使用。