数据结构分类:
- 按逻辑结构分
- 线性结构
- 数组
- 链表
- 栈
- 队列
- 串
- 非线性结构
- 树
- 图或网
- 集合
- 线性结构
- 按存储结构(物理结构)分
- 顺序存储
- 链式存储
- 索引存储
- 散列存储(hash存储)
数组优点:
- 随机存取,随机访问数据,查询效率高,O(1)
- 存储密度高,每个结点只存储数据元素(相对于链表)
数组缺点:
- 创建时需固定数组长度,易造成空间浪费或不足,不足后期扩容效率低;
- 除尾部外其他位置频繁的插入和删除数据,效率低。
动态数组:
1 | /** |
Java 动态数组:
ArrayList
继承关系:
- Iterator 接口:主要用于遍历输出
- Collection接口
- List接口:存储有序的、可重复的数据
- ArrayList 类
- List接口:存储有序的、可重复的数据
- Collection接口
特点:作为List接口的主要实现类;线程不安全的,效率高;底层使用Object[] elementData存储,可加入null
底层源码分析:
1) jdk 7情况下: ArrayList list = new ArrayList();
底层创建了长度是10的Object[]数组elementData,如果添加导致elementData数组容量不够,则扩容。默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)
2) jdk 8中ArrayList的变化: ArrayList list = new ArrayList();
底层Object[] elementData初始化为{}.并没创建长度为10的数组,第一次调用add()时,底层才创建了长度10的数组,并将数据添加到elementData中,后续的添加和扩容操作与jdk 7 无异。
3)小结:jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。
常用方法:
(1)boolean isEmpty():如果列表不包含元素,则返回true。
(2)int size(): 返回此列表中的元素个数。
(3)add(E e) :向列表的尾部添加指定的元素。
(4)void add(int index, E element):在列表的指定位置插入指定元素。
(5)boolean contains(Object o):如果列表包含指定的元素,则返回true。
(6)E get(int index):返回列表中指定位置的元素。
(7)E set(int index, E element):用指定元素替换列表中指定位置的元素。
(8)int indexOf(Object o):返回此列表中第一次出现的指定元素的索引。如果此列表不包含该元素,则返回-1。
(9)int lastIndexOf(Object o):返回此列表中最后出现的指定元素的索引。如果列表不包含此元素,则返回-1。
(10)void clear():从列表中移除所有元素。
(11)E remove(int index):移除列表中指定位置的元素。
(12)boolean remove(Object o):从此列表中移除第一次出现的指定元素(如果存在)。
- Iterator 接口:主要用于遍历输出
vector
继承关系:
- Iterator 接口
- Collection接口
- List接口
- Vetcor 类
- List接口
- Collection接口
特点:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[] elementData存储
底层源码分析:jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。在扩容方面,默认扩容为原来的数组长度的2倍。
- Iterator 接口
- 本文作者: zzr
- 本文链接: http://zzruei.github.io/2023/01feb95590.html
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!