Collection接口是单列集合的主要接口,其下分有List接口和Set接口
List集合:ArrayList、linkedList、Vector
Set集合:HashSet、TreeSet
目录
ArrayList
linkedList
Vector
HashSet
TreeSet
ArrayList
实现了List接口
Arraylist的内部是动态的数组,初始容量为10
但是我们从它的构造方法可以看出它初始化内存的方式是懒汉式的,也就是说创建ArrayList实例时它先不初始化数组大小,当我们添加数据时他才会初始化数组大小。
当然我们可以通过他的另一个构造方法在实例化ArrayList时让它初始化数组长度(大小由我们自定义)
数据添加的方法 add() ,当我们添加数据时会进行数据的比对和数组大小的调整调用方法ensureCapacityInternal(目前数组长度大小 + 1)
先对比初始化大小,如果当前集合未初始化则进行比较大小,大于初始值则返回较大值,若已初始化过大小则直接返回minCapacity。
通过返回获取的参数知道需要扩容后,对比返回参数是否大于原本数组的长度
然后调用grow()方法,将旧的长度赋予oldCapacity,将新的扩容长度赋予newCapacity;
然后对比newCapacity与minCapacity的大小,如果新的扩容长度newCapacity刚好够或大于数据长度则直接使用扩容长度,否则使用数据长度。
下一步是对比新扩容后长度是否超过最大容量(可以扩容的最大容量) - 8,如果超过则再将数据长度与最大容量比较,若超出则使用最大容量。
最后一步是将数据复制到扩容后新创建好的数组中(数组是无法扩大长度的,这里的扩容是创建新数组给定新长度)。
oldCapacity >> 1, >>表示带符号右移,就是将oldCapacity转换为二进制后右移一位,如:0011 >>1 ==> 0001
数据获取的方法 get(),rangeCheck(index)判断是否越界,elementData(index)返回特定index下标的值。
数据删除的方法 remove(),同样先判断是否越界,再判断数据删除后集合是否还有数据,如果还有则复制到新数组,最后将旧数组通过GC垃圾回收机制回收,在返回删除的值。
其他方法
size() 获取长度;
clear() 清除全部;
indexOf(x) 返回指定元素在集合中首次出现的索引
set(number,date) 替换元素
isEmpty() 集合判空
linkedList
linkedList与arraylist不同,它的内部不是用数组存储而是使用链表进行存储
它的添加方法同样是add()因为单列集合接口已经规范好了.
默认采用尾插法添加数据
以下方法可以自己选择从头部或尾部插入
举例尾插法插入,内部会有一个包装类Node,包含3个属性
item:存放数据对象
next:存放下一个节点的指针
prev:存放上一个节点的指针
采用尾插法插入则next为null,l=last是将上一个数据当成prev指针,
如果上一个数据不存在(l==null)则本数据为第一个,如果存在则将本数据当成上个一个数据的next指针(l.next=newNode),size++记录链表长度。
大概的图像
删除方法remove(),大概删除方式如下图,红色线是旧的指针连接,绿色线是删除后的指针连接
其它方法
getFirst() :返回此列表的第一个元素。
getLast() :返回此列表的最后一个元素。
removeFirst() :移除并返回此列表的第一个元素。
removeLast() :移除并返回此列表的最后一个元素。
isEmpty() :集合判空
Vector
Vector是一个出现非常早的矢量队列集合,它同样是使用动态数组进行存储,使用方法也大致与以上单列集合相同,它最大的区别就是他是线程安全的集合,都由synchronized同步方法进行调用。
HashSet
HashSet创建实例的时候默认创建了HashMap来存储数据,因此他很多存储特性都像HashMap,但是HashSet不能存储相同的数据,这样我们就可以使用HashSet来去重。
那HashSet为什么只存储不同的值呢,从以下add()方法中我们可以看到它实际上是调用HashMap的put方法,重点来了!我看到我们存进去的值放在了HashMap的Key的位置而值Value值是PRESNT。现在知道为什么只能存储不同的值了吗,HashMap的Key是不能相同的,它主要的原理就是先对比hashcode是否相同,如果不同则再通过eques方法进行比较,最后才将数据存入。
其它的方法表面上差不多与list相同,其内部都是使用了HashMap的方法。
TreeSet
它是一个有序的不可重复的集合,因为它的结构体是树所以它是有序的,它内部是用TreeMap来存储的。无参构造方法中的this()是调用TreeSet(NavigableMap
存储不重复的方式和HashSet相同都是放在key上。
其它的方法的表示和HashSet相同,但其内部都是使用了TreeMap的方法。



