Java集合专题————Collection

Collection

Collection接口没有直接实现的子类,是通过它的子接口Set和List来实现的

常用方法:

size():判断集合中元素的个数

isEmpty():判断集合是否为空

contains(Object o):检查集合中是否包含指定的对象

toArray():把集合元素存储到数组中

add(E e):添加一个元素

remove(Object o):移除集合中指定的元素

clear():清空集合中所有的元素

Collection的遍历方式

使用Iterator(迭代器)

Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即返回一个迭代器

注意:在调用 iterator.next() 方法之前必须调用 iterator.hasNext() 进行检测,若不调用,且下一条记录无效,直接调用 iterator.next() 会抛出 NoSuchElementException异常

常用方法:

hasNext():判断是否还有下一个元素

next():游标下移;将游标下移后集合位置上的元素返回

Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
	System.out.println(iterator.next());
}

  

使用增强for循环

注意:增强for循环底层仍然是使用迭代器

for(Object obj : collection) {
	System.out.println(obj);
}

  

List

List容器中元素有序、且可重复
List容器中的元素都对应一个索引记载其在容器中的位置,可以根据索引存取容器中的元素(索引是从0开始的)

List集合中添加了一些根据索引来操作集合元素的方法

List的三种遍历方式

方式一:使用iterator
方式二:使用增强for循环
方式三:使用普通for循环

ArrayList

ArrayList可以加入null
ArrayList是由数组来实现数据存储
ArrayList基本等同于Vector,但ArrayList是线程不安全的(执行效率高),在多线程的情况下,不建议使用ArrayList

ArrayList源码的add方法

可以看到该没有 synchronized 修饰

Vector源码的add方法

ArrayList源码解析

ArrayList构造器

ArrayList成员变量

ArrayList中维护了一个Object类型的数组 EMPTY_ELEMENTDATA(transient:被该修饰符修饰的属性不会被序列化)

当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加则扩容elementData为10,如需再次扩容,则扩容elementData为1.5倍

modCount++ 记录集合被修改的次数

真正实现扩容

如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为1.5倍

我的理解:

  • 当调用ArrayList无参构造器创建对象时,此时 elementData 容量为0,第一次插入元素时,elementData直接扩容为10,后续不断添加元素,当要插入第11个元素时候,通过移位运算获得当前最大容量的1.5倍,然后elementData扩容为当前最大容量的1.5倍
  • 当调用ArrayList有参构造函数直接创建指定容量大小的 elementData,后续扩容和上述一致

Vector

Vector底层也是数组

Vector是线程同步的,即线程安全的

Vector源码解析

Vector构造器

Vector成员变量

构造器层层调用

创建Vector对象时,如果使用的是无参构造器,则初始 elementData容量为10,如果需要扩容则直接2倍扩容
创建Vector对象时,如果使用只有一个参数的构造器,则初始 elementData容量为指定值,如果需要扩容直接2倍扩容
创建Vector对象时,如果使用两个参数的构造器,则初始 elementData容量为指定值,如果需要扩容按指定 capacityIncrement值进行扩容(即 elementData.length+capacityIncrement)

 LinkedList

LinkedList底层维护了一个双向链表
LinkedList中维护了两个属性first和last分别指向首节点和尾节点
每个节点里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点

LinkedList底层实现了双端队列特点(删除操作从链表头开始,插入操作从链表尾开始)
LinkedList是线程不安全的

LinkedList源码解析

LinkedList构造器

LinkedList成员变量

Node为LinkedListed的内部类,用于创建一个节点

删除一个节点(删除first指向的节点,即第一个节点)

Set

无序,没有索引
不允许重复元素,所以最多包含一个null

Set的两种遍历方式

方式一:使用迭代器
方式二:使用增强for循环

注意:Set不能通过索引的方式进行遍历

HashSet

HashSet底层实际上是HashMap

HashSet源码解析

HashSet构造器

HashSet成员变量

HashSet第一次执行add(E e)方法时,HashSet的table数组扩容到16,临界值threshold为16*加载因子(loadFactor)=12
HashSet每成功执行一次add(E e),则size++,当size大于threshold时,table就会2倍扩容
如果一条链表的元素个数超过(即元素个数为9)TREEIFY_THRESHOLD(默认值为8)并且 table.length < MIN_TREEIFY_CAPACITY,就会进行红黑树转化
如果一条链表的元素个数超过(即元素个数为9)TREEIFY_THRESHOLD(默认值为8)但 table.length < MIN_TREEIFY_CAPACITY 不成立,则 table 进行2倍扩容

HashSet内部维护着一个HashMap类型的属性

此时进入到HashMap的put方法中

HashMap的成员变量

String类型的hashCode()方法

Integer类型的hashCode()方法

LinkedHashSet

LinkedHashSet是HashSet的子类
LinkedHashSet底层是一个LinkedHashMap,维护了一个数组+双向链表;而LinkedHashMap又继承了HashMap
LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
LinkedHashSet不允许添加重复元素

LinkedHashMap的内部类Entry继承了HashMap的内部类Node

LinkedHashSet源码解析

LinkedHashMap的内部类Entry

原文地址:https://www.cnblogs.com/tang321/p/14787383.html