zoukankan      html  css  js  c++  java
  • 手写ArrayList

    package com.learn.list;

    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.AbstractList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.ConcurrentModificationException;
    import java.util.Iterator;
    import java.util.List;
    import java.util.ListIterator;
    import java.util.NoSuchElementException;
    import java.util.RandomAccess;

    /**
    * 实现 ArrayList的集合(数组)
    *
    */
    public class MyArrayList<E> extends AbstractList<E> implements List<E>,Serializable {
    private static final long serialVersionUID = 123322323L;

    /**
    *default initial capacity
    */
    private static final int DEFAULT_CAPACITY=10;

    /**
    * shared empty array instance used for empty instance
    */
    private static final Object[] EMPTY_ELEMENTDATA={};

    /**
    * 该数组不可序列化 用数组保存元素
    */
    private transient Object[] elementData;
    /**
    * the size of the ArrayList(the number of elements it contains)
    *
    */
    private int size;

    public MyArrayList(int initialCapacity){
    super();//AbstractList父级构造器
    if(initialCapacity<0)
    throw new IllegalArgumentException("Illegal Capacity"+initialCapacity);
    //初始化 指定容器的大小
    this.elementData=new Object[initialCapacity];
    }
    /**
    * constructs an empty list with an initial capacity of ten
    */
    public MyArrayList(){
    super();
    this.elementData=EMPTY_ELEMENTDATA;
    }

    public MyArrayList(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);
    }
    /**
    * 缩容
    */
    public void trimToSize(){
    modCount++;
    if(size<elementData.length){
    elementData=Arrays.copyOf(elementData,size);
    }
    }
    /**
    * 扩容(集合的用起来舒服的原因 就是自动扩容 也称之为可变长度的数组)
    *
    */
    public void ensureCapacity(int minCapacity){
    int minExpand=(elementData!=EMPTY_ELEMENTDATA)?0:DEFAULT_CAPACITY;
    if(minCapacity>minExpand)
    ensureExplicitCapacity(minCapacity);
    }
    private void ensureCapacityInteral(int minCapacity){
    if(elementData==EMPTY_ELEMENTDATA)
    minCapacity=Math.max(DEFAULT_CAPACITY, minCapacity);
    ensureExplicitCapacity(minCapacity);

    }
    private void ensureExplicitCapacity(int minCapacity){
    modCount++;
    if(minCapacity-elementData.length>0)
    grow(minCapacity);
    }
    /**
    * 数组最大不能超过 虚拟机的限制 否则 throw OutOfMemoryError
    */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
    * 扩容 的核心方法 (边界)
    * @param minCapacity
    */
    private void grow(int minCapacity){
    int oldCapacity=elementData.length;
    int newCapacity=oldCapacity+(oldCapacity>>1);//数组扩大 原来的一半
    if(newCapacity-minCapacity<0)
    newCapacity=minCapacity;
    if(newCapacity-MAX_ARRAY_SIZE>0)
    newCapacity=hugeCapacity(minCapacity);
    elementData=Arrays.copyOf(elementData, newCapacity);
    }

    /**
    * 数组 最大的容度
    * @param minCapacity
    * @return
    */
    private static int hugeCapacity(int minCapacity){
    if(minCapacity<0) //overflow
    throw new OutOfMemoryError();
    return (minCapacity>MAX_ARRAY_SIZE)?Integer.MAX_VALUE:MAX_ARRAY_SIZE;
    }

    /**
    * 返回集合大小
    */
    @Override
    public int size() {
    return size;
    }
    /**
    * 判断集合是否为空
    */
    @Override
    public boolean isEmpty() {
    return size==0;
    }
    /**
    * returns <tt>true</tt> if this list contains the specified elements
    * else return <tt> false</tt>
    */
    @Override
    public boolean contains(Object o) {
    return indexOf(o) >= 0;
    }

    /**
    *returns the index of the first occurence of the specified element
    *in this list,or -1 if this list does not contain the element
    */
    @Override
    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;
    }

    /**
    *returns the index if the last occurecce of the specified element
    *in this list ,or -1 if this list doex not contain the element
    */
    @Override
    public int lastIndexOf(Object o) {
    if(o==null){
    for(int i=size-1;i>=0;i--)
    if(elementData[i]==null)
    return i;
    }else{
    for(int i=size-1;i>=0;i--){
    if(o.equals(elementData[i]))
    return i;
    }
    }
    return -1;
    }
    /**
    * 返回一个浅copy ArrayList instance
    */
    public Object clone() throws CloneNotSupportedException{
    try {
    @SuppressWarnings("unchecked")
    MyArrayList<E> v=(MyArrayList<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();
    }
    }
    /**
    * returns an array containing all of the elements in this list
    */
    @Override
    public Object[] toArray() {
    return Arrays.copyOf(elementData, size);
    }

    /**
    * 依据索引获得元素值
    * @param index
    * @return
    */
    E elementData(int index){
    return (E)elementData[index];
    }



    /**
    * 根据下标获取元素
    */
    @Override
    public E get(int index) {
    rangeCheck(index);
    return elementData(index);
    }


    /**
    * 更改指定下标的值 并返回原来的值
    */
    @Override
    public E set(int index, E element) {
    rangeCheck(index);
    E oldValue=elementData(index);
    elementData[index]=element;
    return oldValue;
    }
    /**
    * append the specified element to the end of this list
    */
    @Override
    public boolean add(E e) {
    ensureCapacityInteral(size+1); //Increaments modcount
    elementData[size++]=e; //在 原来集合的大小 添加最后一个元素 即现在集合 size-1位
    return true;
    }
    /**
    * inserts the specified elements at the specified position in this list
    * 原来数组中从当前位置到后面位置 都向后移一位
    */
    @Override
    public void add(int index, E element) {
    rangeCheckForAdd(index);
    ensureCapacityInteral(size+1);
    //从当前位置向后移动一位
    System.arraycopy(elementData, index, elementData, index+1, size-index);
    elementData[index]=element;
    size++;
    }

    /**
    * removes the element at the specified position in this list
    * @param index
    * @return
    */
    @Override
    public E remove(int index) {
    rangeCheck(index);
    modCount++;
    E oldValue=elementData(index);
    int numMoved=size-index-1;//索引从0开始,最后一位 为 size -1 (是最后一位就不需要移动)
    //从当前位置的后一个位置依次向前移动一个位置
    if(numMoved>0)
    System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--size]=null;//clear to let GC do its work
    return oldValue;
    }

    /**
    * removes the first occurrence of the specified element from this list
    * if is is present.
    * if the list does not contain the element ,it is unchanged
    * @param o
    * @return
    */

    @Override
    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 remove method that skips bounds checking and does not
    * return the value removed
    */
    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;//clear to let GC do its work
    }

    /**
    * removes all of the elements from this list.
    * The list will be empty after this call returns
    */
    @Override
    public void clear() {
    modCount++;
    //clear to let GC do its work
    for(int i=0;i<size;i++)
    elementData[i]=null;
    size=0;
    }


    /**
    * 检查范围
    * @param index
    */
    private void rangeCheck(int index){
    if(index>=size)
    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    /**
    * a version of rangecheck by used by add and addAll
    * @param index
    */
    private void rangeCheckForAdd(int index){
    if(index>size||index<0)
    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index){
    return "Index:"+index+",Size:"+size;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
    return false;
    }
    /**
    * Appends all of the elements in the specified collection to the end of this
    * list
    */
    @Override
    public boolean addAll(Collection<? extends E> c) {
    Object[] a=c.toArray();
    int numNew=a.length;
    ensureCapacityInteral(size+numNew);//Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew);
    size+=numNew;
    return numNew!=0;
    }

    /**
    * Inserts all of the elements in the specified collection into this list,
    * starting at the specified position.
    * @param index
    * @param c
    * @return
    */

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    Object[] a=c.toArray();
    int numNew=a.length;
    ensureCapacityInteral(size+numNew);
    int 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;
    }


    /**
    * Removes from this list all of the elements whose index is between
    * [fromIndex,toIndex) fromIndex inclusive,toIndex exclusize
    * @param fromIndex
    * @param toIndex
    */
    protected void removeRange(int fromIndex,int toIndex){
    modCount++;
    int numMoved=size-toIndex;
    System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
    int newSize=size-(toIndex-fromIndex);
    for(int i =newSize;i<size;i++)
    elementData[i]=null;
    size=newSize;
    }
    /**
    *removes from this list all of its elements that are contained in the
    *specified collection
    */
    @Override
    public boolean removeAll(Collection<?> c) {
    return batchRemove(c,false);
    }
    /**
    *retains only the elements in this list that are contained in the specified collection
    * @param c
    * @return
    */
    @Override
    public boolean retainAll(Collection<?> c) {
    return batchRemove(c,true);
    }

    private boolean batchRemove(Collection<?> c,boolean complement){
    final Object[] elementData=this.elementData;
    int r=0,w=0;//w中记录要保留的元素
    boolean modified=false;
    try{
    for(;r<size;r++)
    if(c.contains(elementData[r])==complement)
    elementData[w++]=elementData[r];
    }finally{
    //如果在赋值的同时发生异常,集合中没有走完的元素赋值给 w
    if(r!=size){
    System.arraycopy(elementData, r, elementData, w, size-r);
    w+=size-r;
    }
    if(w!=size){
    //clear to let GC do its work
    for(int i=w;i<size;i++)
    elementData[i]=null;
    modCount+=size-w;
    size=w;
    modified=true;
    }
    }
    return modified;
    }

    /**
    * save the state of the ArrayList instance to a stream
    * @param s
    * @throws java.io.IOException
    */
    private void writeObject(ObjectOutputStream s) throws java.io.IOException{
    int expectedMoCount=modCount;
    s.defaultWriteObject();
    //write out size as capacity for behavioural compatibility with clone
    s.writeInt(size);
    //Write Out all elements in the proper order
    for(int i=0;i<size;i++)
    s.writeObject(elementData[i]);
    if(modCount!=expectedMoCount)
    throw new ConcurrentModificationException();
    }
    /**
    * Reconstitute the ArrayList instance from a stream
    * @param s
    * @throws java.io.IOException
    * @throws ClassNotFoundException
    */
    private void readObject(ObjectInputStream s) throws java.io.IOException, ClassNotFoundException{
    elementData=EMPTY_ELEMENTDATA;
    //Read in size,and any hidden stuff
    s.defaultReadObject();
    //Read in capacity
    s.readInt();
    if(size>0){
    ensureCapacityInteral(size);
    //be like clone(),allocate array based upon size not capacity
    Object[] a=elementData;
    for(int i=0;i<size;i++){
    a[i]=s.readObject();
    }
    }
    }
    /**
    * returns an iterator over the elements in this list in proper sequence
    */
    @Override
    public Iterator<E> iterator() {
    return new Itr();
    }


    @Override
    public ListIterator<E> listIterator() {
    // TODO Auto-generated method stub
    return null;
    }

    @Override
    public ListIterator<E> listIterator(int index) {
    // TODO Auto-generated method stub
    return null;
    }

    /**
    * an optimized version of
    * @author c_xulei025
    *
    */
    private class Itr implements Iterator<E>{
    int cursor;//index of next elements to return
    int lastRet=-1;//index of last elements returned;-1 if no such
    int expectedModCount=modCount;
    @Override
    public boolean hasNext() {
    return cursor!=size;
    }

    @SuppressWarnings("unchecked")
    @Override
    public E next() {
    checkForComodification();
    int i=cursor;
    if(i>size)
    throw new NoSuchElementException();
    Object[] elementData=MyArrayList.this.elementData;
    if(i>=elementData.length)
    throw new ConcurrentModificationException();
    cursor=i+1;
    return (E) elementData[lastRet=i];
    }

    @Override
    public void remove() {
    if(lastRet<0)
    throw new IllegalStateException();
    checkForComodification();
    try{
    MyArrayList.this.remove(lastRet);
    cursor=lastRet;
    lastRet=-1;
    expectedModCount=modCount;
    }catch(IndexOutOfBoundsException ex){
    throw new ConcurrentModificationException();
    }

    }
    final void checkForComodification(){
    if(modCount!=expectedModCount)
    throw new ConcurrentModificationException();
    }

    }

    private class ListItr extends Itr implements ListIterator<E>{
    ListItr(int index){
    super();
    cursor=index;
    }

    @Override
    public boolean hasPrevious() {
    return cursor!=0;
    }


    @Override
    public int nextIndex() {
    return cursor;
    }

    @Override
    public int previousIndex() {
    return cursor-1;
    }


    @SuppressWarnings("unchecked")
    @Override
    public E previous() {
    checkForComodification();
    int i=cursor-1;
    if(i<0)
    throw new NoSuchElementException();
    Object[] elementData=MyArrayList.this.elementData;
    if(i>=elementData.length)
    throw new ConcurrentModificationException();
    cursor=i;
    return (E) elementData[lastRet=i];
    }

    @Override
    public void set(E e) {
    if(lastRet<0)
    throw new IllegalStateException();
    checkForComodification();
    try {
    MyArrayList.this.set(lastRet, e);
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }

    @Override
    public void add(E e) {
    checkForComodification();
    try{
    int i=cursor;
    MyArrayList.this.add(i,e);
    cursor=i+1;
    lastRet=-1;
    expectedModCount=modCount;
    }catch(IndexOutOfBoundsException ex){
    throw new ConcurrentModificationException();
    }
    }

    }
    /**
    * returns a view of the portion of this list between the specified
    * fromIndex,inclusive and toIndex,exclusive
    *
    * @param fromIndex
    * @param toIndex
    * @return
    */
    @Override
    public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
    }
    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
    if (fromIndex < 0)
    throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
    if (toIndex > size)
    throw new IndexOutOfBoundsException("toIndex = " + toIndex);
    if (fromIndex > toIndex)
    throw new IllegalArgumentException("fromIndex(" + fromIndex +
    ") > toIndex(" + toIndex + ")");
    }
    protected transient int modCount = 0;

    private class SubList extends AbstractList<E> implements RandomAccess{
    private final AbstractList<E> parent;
    private final int parentOffset;
    private final int offset;
    int size;

    SubList(AbstractList<E> parent,
    int offset, int fromIndex, int toIndex) {
    this.parent = parent;
    this.parentOffset = fromIndex;
    this.offset = offset + fromIndex;
    this.size = toIndex - fromIndex;
    this.modCount = MyArrayList.this.modCount;
    }

    public E set(int index, E e) {
    rangeCheck(index);
    checkForComodification();
    E oldValue = MyArrayList.this.elementData(offset + index);
    MyArrayList.this.elementData[offset + index] = e;
    return oldValue;
    }

    public E get(int index) {
    rangeCheck(index);
    checkForComodification();
    return MyArrayList.this.elementData(offset + index);
    }

    public int size() {
    checkForComodification();
    return this.size;
    }

    public void add(int index, E e) {
    rangeCheckForAdd(index);
    checkForComodification();
    parent.add(parentOffset + index, e);
    this.size++;
    }

    public E remove(int index) {
    rangeCheck(index);
    checkForComodification();
    E result = parent.remove(parentOffset + index);
    this.size--;
    return result;
    }

    protected void removeRange(int fromIndex, int toIndex) {
    checkForComodification();
    this.size -= toIndex - fromIndex;
    }

    public boolean addAll(Collection<? extends E> c) {
    return addAll(this.size, c);
    }

    public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    int cSize = c.size();
    if (cSize==0)
    return false;

    checkForComodification();
    parent.addAll(parentOffset + index, c);
    this.size += cSize;
    return true;
    }

    public Iterator<E> iterator() {
    return listIterator();
    }

    public ListIterator<E> listIterator(final int index) {
    checkForComodification();
    rangeCheckForAdd(index);
    final int offset = this.offset;

    return new ListIterator<E>() {
    int cursor = index;
    int lastRet = -1;
    int expectedModCount = MyArrayList.this.modCount;

    public boolean hasNext() {
    return cursor != SubList.this.size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= SubList.this.size)
    throw new NoSuchElementException();
    Object[] elementData = MyArrayList.this.elementData;
    if (offset + i >= elementData.length)
    throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[offset + (lastRet = i)];
    }

    public boolean hasPrevious() {
    return cursor != 0;
    }

    @SuppressWarnings("unchecked")
    public E previous() {
    checkForComodification();
    int i = cursor - 1;
    if (i < 0)
    throw new NoSuchElementException();
    Object[] elementData = MyArrayList.this.elementData;
    if (offset + i >= elementData.length)
    throw new ConcurrentModificationException();
    cursor = i;
    return (E) elementData[offset + (lastRet = i)];
    }

    public int nextIndex() {
    return cursor;
    }

    public int previousIndex() {
    return cursor - 1;
    }

    public void remove() {
    if (lastRet < 0)
    throw new IllegalStateException();
    checkForComodification();

    try {
    SubList.this.remove(lastRet);
    cursor = lastRet;
    lastRet = -1;
    expectedModCount = MyArrayList.this.modCount;
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }

    public void set(E e) {
    if (lastRet < 0)
    throw new IllegalStateException();
    checkForComodification();

    try {
    MyArrayList.this.set(offset + lastRet, e);
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }

    public void add(E e) {
    checkForComodification();

    try {
    int i = cursor;
    SubList.this.add(i, e);
    cursor = i + 1;
    lastRet = -1;
    expectedModCount = MyArrayList.this.modCount;
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }

    final void checkForComodification() {
    if (expectedModCount != MyArrayList.this.modCount)
    throw new ConcurrentModificationException();
    }
    };
    }

    public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, offset, fromIndex, toIndex);
    }

    private void rangeCheck(int index) {
    if (index < 0 || index >= this.size)
    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private void rangeCheckForAdd(int index) {
    if (index < 0 || index > this.size)
    throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
    return "Index: "+index+", Size: "+this.size;
    }

    private void checkForComodification() {
    if (MyArrayList.this.modCount != this.modCount)
    throw new ConcurrentModificationException();
    }
    }
    }

  • 相关阅读:
    (五)Hibernate 操作对象
    (四)关联关系一对多映射
    (三)映射对象标识符(OID)
    随机取数据
    Delphi的时间处理
    调用MYSQL存储过程实例
    php接收数据
    NodeJS入门
    idHTTP访问百度
    delphi 从TWebBrowser WebBrowser得到全部html源码
  • 原文地址:https://www.cnblogs.com/caibixiang123/p/7978533.html
Copyright © 2011-2022 走看看