Java集合(二)List集合

注:原博客 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()取出栈顶元素,并删除,取出数组末尾元素并删除

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值