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