注:原博客 http://www.cnblogs.com/skywang12345/p/3323085.html,我仅是梳理做学习笔记
1.ArrayList集合
(1)ArrayList简介
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.ArrayList<E>
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
ArrayList动态数组,线程不安全,单线程中使用,多线程使用vector或者copyonwritearraylist
ArrayList继承AbstractList,实现了List,提供了添加删除修改遍历等
ArrayList实现了RandomAccess提供了随机访问的功能
ArrayList实现了Cloneable接口,即覆盖了函数clone,能够被克隆
ArrayList实现了Serializable接口,支持序列化,能通过序列化去传输
ArrayList中两个重要的对象:elementData 和 size。
1)elementDate:保存添加到ArrayList中的元素,是一个动态数组,我们通过构造函数可以指定初始化容量,默认容量10,如果需要增长容量,增长规则:新的容量=“(原始容量x3)/2 + 1”
2)size是动态数组的实际大小
(2)ArrayList重点源码分析
public class ArrayList<E> extends AbstractList<E>
implements List<E>,RandomAccess,Cloneable,java.io.Serializable{
// 保存ArrayList中数据的数组
private transient Object[] elementData;
// ArrayList中实际数据的数量
private int size;
//三个构造函数,简要说明:指定容量大小的构造函数,默认构造函数大小10,创建包含Collection的ArrayList
// 将当前容量值设为 =实际元素个数
public void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (size < oldCapacity) {
elementData = Arrays.copyOf(elementData, size);
}
}
// 确定ArrarList的容量,当ArrayList容量不足,设置新容量=(原始容量*3)/2+1
public void ensureCapacity(int minCapacity) {
// 将“修改统计数”+1
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
//添加元素:add(E)
//实际大小:size()
//是否包含某元素:contains(Object)
//判断是否为空:isEmpty()
//正向查找,返回元素的索引值:indexOf(Object)
//反向查找,返回元素的索引值:lastIndexOf(Object)
//获取index位置的元素值:get(index)
//设置index位置的值为element:set(index,Element)
//将e添加到ArrayList中:add(E),添加到指定位置:add(index,E)
//删除指定位置的元素:remove(index),删除某元素:remove(Object)
//清空ArrayList:clear(),全部设置为null
//删除从from到to之间的全部元素:removeRange(from,to)
}
(3)ArrayList遍历方式
通过随机访问效率最高,使用迭代器效率最低 1)通过迭代器Iterator遍历
Iterator iter = list.iterator();
while(iter.hasNext()){
System.out.print(iter.next());
}
2)通过随机访问,通过索引值遍历
Integer value = null;
int size = list.size();
for (int i=0; i<size; i++) {
value = (Integer)list.get(i);
}
3)for循环遍历
for(int i = 0; i < stringList.size();i++){
System.out.print(stringList.get(i));
}
2.LinkedList集合
(1)LinkedList简介
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.AbstractSequentialList<E>
↳ java.util.LinkedList<E>
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}
LinkedList是一个继承AbstractSequentiaList的双向链表,可以当做栈,队列或者双端队列进行操作
LinkedList实现了List,能对队列进行操作
LinkedList实现了Deque接口,能对双端队列进行操作
LinkedList实现了Serializable,可以支持序列化,它是非同步的
LinkedList的本质是双向链表,它的两个重要成员:header和siz
1)header:双向链表的表头,它是Entry实例。Entry中的成员变量:previous,next,element
2)size:是双向链表的节点的个数
(2)LinkedList重点源码分析
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable{
// 链表的表头,表头不包含任何数据。Entry是个链表类数据结构。
private transient Entry<E> header = new Entry<E>(null, null, null);
// LinkedList中元素个数
private transient int size = 0;
//两个构造函数,无参,创建一个包含集合的LinkedList
//获取第一个元素:getFirst(),获取最后一个元素:getLast()
//删除第一个元素:removeFirst(),删除最后一个:removeLast()
//将元素添加到起始位置:addFirst(),添加到结束位置:addLast()
//是否包含某元素:contains(Object)
//添加元素:add(E),删除元素remove(E)
//将集合添加到LinkedList:addAll(Collection),从链表的index开始,添加集合:addAll(index,Collection)
//获取某位置的元素:get(index),设置某位置元素:set(index)
//删除并返回第一个节点:poll(),如果大小为0,返回null
//删除并返回最后一个节点:peekLast(),如果大小为0,返回null
//从链表头向后查找,删除第一个值为元素o的节点:removeFirstOccurrence(o)
//从链表尾开始查找,删除第一个值为元素o的节点:removeLastOccurrence(o)
//方法太多了,原理挺简单的,就是链表的操作
}
LinkedList不存在容量不足的问题,同时它实现了serializable接口,当写入到输出流时,先写入容量,在写入每一个节点的值;当读出输出流先读取容量,在读取每一个元素
(3)LinkedList遍历方式
1)通过迭代器(Iterator)遍历
for(Iterator iter = list.iterator(); iter.hasNext();)
iter.next();
2)通过快速随机访问这个其实我感觉就是for循环,那么就不解释增强for了
int size = list.size();
for (int i=0; i<size; i++) {
list.get(i);
}
3)通过pollFirst/pollLast遍历:
while(list.pollFirst() != null);
while(list.pollLast() != null);
4)通过removeFirst/removeLast遍历:
try {
while(list.removeFirst() != null)
;
} catch (NoSuchElementException e) {
}
try {
while(list.removeLast() != null)
;
} catch (NoSuchElementException e) {
}
通过removeFirst/removeLast效率最高,但是会删除元素数据,如果只是单独的读取不删除数据,可以使用for遍历,通过随机访问太慢慢
3.Vector集合
(1)Vector简介
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.Vector<E>
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
Vector是矢量队列,它是JDK1.0添加的类,继承于AbstractList,实现了List,所以是一个队列,支持添加,删除,遍历,修改等功能。实现了RandomAccess接口,即提供了随机访问的功能,在Vector中我们可以通过元素的序号快速获取元素。实现了Cloneable就可以clone()克隆。但是与ArrrayList不同,它是线程安全的。
Vector和ArrayList的继承关系差不多,它有三个成员变量:elementData,elementCount,capacityIncrement 1)elementData:它保存了添加到Vector中的元素,elementData是动态数组,默认初始化大小10,当元素增加,会动态增长,增长方式:当容量系数>0(capacityIncrement>0),将容量的值增加"capacityIncrement",否则将容量扩大一倍。
2)elementCount:动态数组的实际大小
3)capacityIncrement:动态数组的增长系数
(2)Vector重点源码分析
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// 保存Vector中数据的数组
protected Object[] elementData;
// 实际数据的数量
protected int elementCount;
// 容量增长系数
protected int capacityIncrement;
//4个构造函数:无参默认容量10;vector(int,int)指定容量大小和增长系数的构造函数;vector(Collection)指定集合的构造函数;vector(int)指定容量大小的构造函数
//将vector的全部元素都拷贝到数组中
public synchronized void copyInto(Object[] anArray)
//将当前容量设置=实际元素个数
public synchronized void trimToSize()
//容量增长的帮助函数
private void ensureCapacityHelper(int minCapacity)
//设置容量值为newsize
public synchronized void setSize(int newSize)
public synchronized int capacity()//返回总容量
public synchronized int size()//返回实际大小
public synchronized boolean isEmpty()//判断是否为空
public Enumeration<E> elements()//返回Vector中的全部元素对应的Enumberation
public synchronized int indexOf(Object o, int index)从inedx位置开始向后查找元素o,如果找到,返回元素索引,没找到-1
public synchronized E elementAt(int index)返回index位置的元素
public synchronized void setElementAt(E obj, int index) 设置index处的元素为obj
public synchronized void removeElementAt(int index)删除index处的元素
public synchronized void insertElementAt(E obj, int index)在index处插入元素E
}
(3)遍历Vector
1)迭代器(Iterator)
Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
value = (Integer)vec.get(i);
}
2)随机访问:
Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
value = (Integer)vec.get(i);
}
3)Enumberation: Integer value = null; Enumeration enu = vec.elements(); while (enu.hasMoreElements()) { value = (Integer)enu.nextElement(); } 通过随机访问效率最快,使用迭代器最慢
4.Stack集合
(1)Stacke简介
Stack是栈,它的特点是先进后出,因为继承于Vector(通过数组实现),所以Stack也是通过数组实现,并非链表
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.Vector<E>
↳ java.util.Stack<E>
public class Stack<E> extends Vector<E> {}
(2)Stack重点源码分析
public class Stack<E> extends Vector<E> {
// 版本ID。这个用于版本升级控制,这里不须理会!
private static final long serialVersionUID = 1224463164541339165L;
// 构造函数
public Stack() {
}
// push函数:将元素存入栈顶
public E push(E item) {
// 将元素存入栈顶。
// addElement()的实现在Vector.java中
addElement(item);
return item;
}
// pop函数:返回栈顶元素,并将其从栈中删除
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
// 删除栈顶元素,removeElementAt()的实现在Vector.java中
removeElementAt(len - 1);
return obj;
}
// peek函数:返回栈顶元素,不执行删除操作
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
// 返回栈顶元素,elementAt()具体实现在Vector.java中
return elementAt(len - 1);
}
// 栈是否为空
public boolean empty() {
return size() == 0;
}
// 查找“元素o”在栈中的位置:由栈底向栈顶方向数
public synchronized int search(Object o) {
// 获取元素索引,elementAt()具体实现在Vector.java中
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
}
1)push(),元素推入栈中,将元素追加到数组的末尾
peek()取出栈顶元素,返回数组中的末尾元素
pop()取出栈顶元素,并删除,取出数组末尾元素并删除