目录
2.3 ArrayList 和 LinkedList 的区别
1.Java常见的集合
Java常见的集合主要分为3种:List(列表)、Map(映射)、Set(集),集合相关类和接口都在java.util中。本文主要介绍List集合
Java主要集合关系
2.List集合
2.1 ArrayList 和 Array(数组)的区别
ArrayList
内部基于动态数组实现,比 Array
(静态数组) 使用起来更加灵活:
ArrayList
会根据实际存储的元素动态地扩容或缩容,而Array
被创建之后就不能改变它的长度了。ArrayList
允许你使用泛型来确保类型安全,Array
则不可以。ArrayList
中只能存储对象。对于基本类型数据,需要使用其对应的包装类(如 Integer、Double 等)。Array
可以直接存储基本类型数据,也可以存储对象。ArrayList
支持插入、删除、遍历等常见操作,并且提供了丰富的 API 操作方法,比如add()
、remove()
等。Array
只是一个固定长度的数组,只能按照下标访问其中的元素,不具备动态添加、删除元素的能力。ArrayList
创建时不需要指定大小,而Array
创建时必须指定大小。
2.2 ArrayList 和 Vector 的区别
- Vector的方法都是同步的,是线程安全的,而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
- 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList 会增加其容量的一半,这是通过将原始数组复制到新的数组来完成的。这样,ArrayList就有利于节约内存空间。
2.3 ArrayList 和 LinkedList 的区别
- 数据结构不同:ArrayList基于数组实现,LinkedList基于双向链表实现。
- 是否保证线程安全:
ArrayList
和LinkedList
都是不同步的,也就是不保证线程安全。 - 内存空间占用:
ArrayList
的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。 - 是否支持随机访问:ArrayList基于数组,所以它可以根据下标查找,支持随机访问,当然,它也实现了RandmoAccess 接口,这个接口只是用来标识是否支持随机访问。LinkedList基于链表,所以它没法根据序号直接获取元素,它没有实现RandmoAccess 接口,标记不支持随机访问。
- 使用优势:ArrayList更利于查找,LinkedList更利于增删。
2.4 ArrayList 的扩容机制
ArrayList是基于数组的集合,数组的容量是在定义的时候确定的,如果数组满了,再插入,就会数组溢出。所以在插入时候,会先检查是否需要扩容,如果当前容量+1超过数组长度,就会进行扩容。ArrayList的扩容是创建一个1.5倍的新数组,然后把原数组的值拷贝过去。
3.实现 ArrayList 线程安全的方法
fail-fast是一种可能触发的机制,实际上,ArrayList的线程安全仍然没有保证,一般,保证ArrayList的线程安全可以通过这些方案:
- 使用 Vector 代替 ArrayList。(不推荐,Vector是一个历史遗留类)
- 使用 Collections.synchronizedList 包装 ArrayList,然后操作包装后的 list。
- 使用 CopyOnWriteArrayList 代替 ArrayList。
- 在使用 ArrayList 时,应用程序通过同步机制去控制 ArrayList 的读写。