java集合之arrayList

来源:互联网 发布:淘宝卖家不发货处罚 编辑:程序博客网 时间:2024/04/29 23:18
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法 并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
首先,我们来arrayList 的常用 方法,对他有一个具体的了解。
public static void main(String[] args) {//jdk1.5 提倡使用泛型,更加安全,表示list中的元素必须全部为String类型List<String> list=new ArrayList<String>();//增加一个元素list.add(0, "第一个元素");list.add("第二个元素");//输出指定元素所在的位置,如果不存在,则返回-1System.out.println(list.indexOf("第一个元素"));//删除第二个元素list.remove(1);System.out.println(list);list.add("元素2");list.add("元素3");//遍历list输出for(int i=0;i<list.size();i++){System.out.println(list.get(i));}//从后往前输出for(int i=(list.size()-1);i>=0;i--){System.out.println(list.get(i));}//将类集转化为数组,因为类型定义时为String型的,//所以数组也要定义为String类型的数组String str[]=list.toArray(new String[]{ });System.out.println("指定的数组类型:");for(int i=0;i<str.length;i++){System.out.println(str[i]+";");}                //只要是类集的,最标准的迭代方法。Iterator<String> iter=list.iterator();while(iter.hasNext()){String str1=iter.next();System.out.println(str1);}}

从以上方法中可以看出arrayList 支持查找数组中元素的位置,增加元素,删除元素等功能,但是他的复杂性如何呢?下面我们对arrayList 的源码进行研究


package java.util; //arrayList在util包之中 //arrayList继承于AbstractList,它也是collection的一个子类, //1.实现了Serializable接口,因此它支持序列化,能够通过序列化传输 //2.实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问, //3.实现了Cloneable接口,能被克隆。 public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {    private static final long serialVersionUID = 8683452581122892189L;    /**     *<span><span class="comment"> ArrayList基于该数组实现,用该数组保存数据</span></span>     *      */    private transient Object[] elementData;    /**     * 数组的长度     *     * @serial     */    private int size;    /**     * 带初始化容量的构造方法     *     * @param   initialCapacity   the initial capacity of the list     * @exception IllegalArgumentException if the specified initial capacity     *            is negative     */    public ArrayList(int initialCapacity) {super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);this.elementData = new Object[initialCapacity];    }    /**     * 默认的构造方法,初始容量为10     */    public ArrayList() {this(10);    }    /**     * <span><span class="comment">创建一个包含collection的ArrayList </span></span>     *     * @param c  一个collection     * @throws NullPointerException if the specified collection is null     */    public ArrayList(Collection<? extends E> c) {elementData = c.toArray();size = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)    elementData = Arrays.copyOf(elementData, size, Object[].class);    }    /**     * <span><span class="comment">将当前容量值设为实际元素个数 </span></span>     */    public void trimToSize() {modCount++;int oldCapacity = elementData.length;if (size < oldCapacity) {            elementData = Arrays.copyOf(elementData, size);}    }    /**     * <span><span class="comment">确定ArrarList的容量。  </span><span>  </span>        *<span class="comment"> 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”  </span><span>  </span></span>     *     * @param   minCapacity   the desired minimum capacity     */    public void ensureCapacity(int minCapacity) {modCount++;int oldCapacity = elementData.length;if (minCapacity > oldCapacity) {    Object oldData[] = elementData;    int newCapacity = (oldCapacity * 3)/2 + 1;        if (newCapacity < minCapacity)newCapacity = minCapacity;            // minCapacity is usually close to size, so this is a win:            elementData = Arrays.copyOf(elementData, newCapacity);}    }    /**     * 返回arrayList的长度     *     * @return the number of elements in this list     */    public int size() {return size;    }    /**     * 判断此arrayList是否为空     */    public boolean isEmpty() {return size == 0;    }    /**     *判断此arrayList中是否包含此对象     *     */    public boolean contains(Object o) {return indexOf(o) >= 0;    }    /**     * 判断此arrayList中是否包含此对象<pre name="code" class="java">     * 并返回对象所在的坐标,如果没有此对象返回-1     */    public int indexOf(Object o) {if (o == null) {    for (int i = 0; i < size; i++)if (elementData[i]==null)    return i;} else {    for (int i = 0; i < size; i++)if (o.equals(elementData[i]))    return i;}return -1;    }    <span>    </span>    /**     * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The     * elements themselves are not copied.)     *     * @return a clone of this <tt>ArrayList</tt> instance     */    public Object clone() {try {    ArrayList<E> v = (ArrayList<E>) super.clone();    v.elementData = Arrays.copyOf(elementData, size);    v.modCount = 0;    return v;} catch (CloneNotSupportedException e) {    // this shouldn't happen, since we are Cloneable    throw new InternalError();}    }    public Object[] toArray() {        return Arrays.copyOf(elementData, size);    }       public <T> T[] toArray(T[] a) {        if (a.length < size)            // Make a new array of a's runtime type, but my contents:            return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);        if (a.length > size)            a[size] = null;        return a;    }       <span> <span class="comment">// 获取index位置的元素值 </span></span>    public E get(int index) {RangeCheck(index);return (E) elementData[index];    }   <span> <span class="comment">// 设置index位置的值为element</span></span>    public E set(int index, E element) {RangeCheck(index);E oldValue = (E) elementData[index];elementData[index] = element;return oldValue;    }    <span><span class="comment">// 将e添加到ArrayList中 </span></span>    // 每次添加之前都要调用ensureCapacity()方法来保证数组可以容纳    public boolean add(E e) {ensureCapacity(size + 1);  // Increments modCount!!elementData[size++] = e;return true;    }    //在指定位置添加元素    public void add(int index, E element) {    //范围不合理,报异常    if (index > size || index < 0)    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);ensureCapacity(size+1); <pre>        //<span style="font-family:SimSun;font-size:14px;"><span style="color:red;"> </span><span style="font-size:12px;color:red;">这里可以很明显地看出,</span><span style="color:#ff0000;"><span style="font-size:12px;">该方法实际上是在其内部又创建了一个长度为newlength的数组,</span></span></span>        //<span style="font-family:SimSun;font-size:14px;"><span style="color:#ff0000;"><span style="font-size:12px;"> 调用System.arraycopy()方法</span>,<span style="font-size:12px;">将原来数组中的元素复制到了新的数组中</span>。</span></span>System.arraycopy(elementData, index, elementData, index + 1, size - index);elementData[index] = element;size++;    }    //删除元素,步骤:1.将要删除的元素赋值给一个变量;2.    public E remove(int index) {RangeCheck(index);modCount++;E oldValue = (E) elementData[index];int numMoved = size - index - 1;if (numMoved > 0)    System.arraycopy(elementData, index+1, elementData, index,     numMoved);elementData[--size] = null; // Let gc do its workreturn oldValue;    }    //删除元素    public boolean remove(Object o) {if (o == null) {            for (int index = 0; index < size; index++)if (elementData[index] == null) {    fastRemove(index);    return true;}} else {    for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {    fastRemove(index);    return true;}        }return false;    }       private void fastRemove(int index) {        modCount++;        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // Let gc do its work    }    //清空arrayList    public void clear() {modCount++;// Let gc do its workfor (int i = 0; i < size; i++)    elementData[i] = null;size = 0;    }       public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();        int numNew = a.length;ensureCapacity(size + numNew);  // Increments modCount        System.arraycopy(a, 0, elementData, size, numNew);        size += numNew;return numNew != 0;    }       public boolean addAll(int index, Collection<? extends E> c) {if (index > size || index < 0)    throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);Object[] a = c.toArray();int numNew = a.length;ensureCapacity(size + numNew);  // Increments modCountint numMoved = size - index;if (numMoved > 0)    System.arraycopy(elementData, index, elementData, index + numNew,     numMoved);        System.arraycopy(a, 0, elementData, index, numNew);size += numNew;return numNew != 0;    }       protected void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = size - toIndex;        System.arraycopy(elementData, toIndex, elementData, fromIndex,                         numMoved);// Let gc do its workint newSize = size - (toIndex-fromIndex);while (size != newSize)    elementData[--size] = null;    }       private void RangeCheck(int index) {if (index >= size)    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);    }       private void writeObject(java.io.ObjectOutputStream s)        throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();        // Write out array length        s.writeInt(elementData.length);// Write out all elements in the proper order.for (int i=0; i<size; i++)            s.writeObject(elementData[i]);if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }    }    <span><span class="comment">// java.io.Serializable的读取函数:根据写入方式读出  </span><span>  </span></span><span>    <span class="comment">// 先将ArrayList的“容量”读出,然后将“所有的元素值”读出  </span></span><span><span></span></span>    private void readObject(java.io.ObjectInputStream s)        throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuffs.defaultReadObject();        // Read in array length and allocate array        int arrayLength = s.readInt();        Object[] a = elementData = new Object[arrayLength];// Read in all elements in the proper order.for (int i=0; i<size; i++)            a[i] = s.readObject();    }}




0 0
原创粉丝点击