java集合体系结构总结

 好,首先我们根据这张集合体系图来慢慢分析。大到顶层接口,小到具体实现类。

首先,我想说为什么要用集合?简单的说:数组长度固定,且是同种数据类型。不能满足需求。所以我们引入集合(容器)来存储任意数据类型的可变大小的数据。

来了解下数组:

数组有静态、动态之分。但是其长度都是固定的,并且其内部只能存储同一种数据类型的数据。除非是Object类型的数组,它可以存储任意类型的数据。

数组的存储方式?数据存储结构分为顺序存储、链接存储、索引存储、散列存储
数组是基于顺序存储方式。数组就是在内存中开辟一块连续的、大小相同的空间,用来存储数据。
数组查询速度快:因为基于索引查询。但是增删慢。为什么增删慢呢?因为数组的元素是连续的(索引是连续的)。如果要增删元素时,会发生索引位置的移动,且是重新创建了一个新数组。所以增删慢。

 


java集合体系结构中主要按两种接口分类:

1.Collection
2. Map

//查看jdk1.8源码

首先分析Collection,它是一个接口,同时它继承了顶级Iterable接口,为什么要继承这个接口呢?主要是使用接口中特有
方法,可以通过iterator迭代器遍历整个集合。在jdk1.8中,Iterable接口中有forEach方法、spliterator()方法。

同时,List接口继承了Collection接口.List是存取有序可重复且有索引的,同时允许元素为null。这里所说的有序是元素的存取顺序。Set是无序不可重复无索引。但是Set的无序我们一般是指HashSet,因为它不能保证元素的存取顺序和自然排序。而LinkedHashSet:保证元素的添加顺序。TreeSet:保证元素的自然排序。可能知道的人很容易理解,不知道的人不理解就很难记忆。通过代码,也可以清楚看到是否有序,是否重复的特性。由于篇幅,演示代码省略。接下来我们逐一分析接口下的实现类都有什么特性?

List接口下的实现类

ArrayList底层是使用了Object数组实现的,查询速度快,增删慢。非同步的(线程不安全类),因此效率高。数组默认容量是10,当长度不够时自动增长0.5倍,也就是原数组的1.5倍。

使用场景:频繁查询时,增删较少时。

LinkedList:底层结构是双向链表,不需要在内存中开辟一段连续的内存空间。而是每个元素有一个下一元素地址]这样的内存结构。增加时只需要改变两个节点之间的引用关系即可。来组成一个新的节点。删除时只要删除两个节点的引用即可。而查询时,必须从头部开始查询。所以效率慢。查询慢,增删快同时它是非同步的(线程不安全)。https://blog.csdn.net/qq_35120695/article/details/56573865

Vector: 底层也是基于动态数组实现。线程安全类,但是效率低,基本不使用。

Set接口下的实现类

 HashSet:jdk1.8中,哈希表底层采用数组+链表+红黑树实现,其实现set接口,底层使用HashMap来保存所有元素。特点:无序不可重复。线程不安全。其是如何保证去重原理的呢?

从源码中我们可以看出:
它的add()方法实际上调用的是HashMap中的put()方法,把要添加进HashSet中的元素当做key存入,而value则是一个固定值:一个Object类对象。
先用hashCode()方法获得传入元素的哈希值,在集合中查找是否包含哈希值相同的元素,如果相同,则继续进行比较它们地址值,一般地址值都是不相同的,所以最后会用equals()方法比较对象内的属性值。
比较结果全为false就存入,如果比较结果有true则不存。

TreeSet:底层使用TreeMap来进行存储,而TreeMap底层基于红黑树数据结构,规则是左小右大。有序不可重复。有序指对元素进行自然排序。同时支持定制排序。线程不安全类

TreeSet注意事项:
1、往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素本身的自然顺序特性进行存储;
2、如果元素本身不具备自然 顺序的特性,那么该元素所属的类必须要实现Comparable接口,并重写compareTo()
方法,把元素的比较规则定义在compareTo()方法上;
3、如果比较元素的时候,compareTo()方法返回的是0,那么该元素就被视为重复元素,不允许添加;

LinkedHashSet:其继承了HashSet,内部是通过 LinkedHashMap 来实现的。有序指保证元素的添加顺序。

猜你喜欢

转载自www.cnblogs.com/mukk/p/12301189.html