复写ArrayList源码


import java.util.AbstractList;
import java.util.ArrayList;
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.Objects;
import java.util.RandomAccess;


/**
 * 复写ArrayList源码
 * 扩容为原数组的1.5倍
 * @author Administrator
 *
 */
public class OverrideArrayList<E> extends AbstractList<E>
		implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
	// List<> list=new ArrayList<>();

	// 设置默认容量为10
	private static final int DEFAULT_CAPACITY = 10;

	// 创造一个空数组用来装元素 有参构造初始容量为0的空数组
	private static final Object[] EMPTY_ELEMENTDATA = {};

	// 创造一个空数组用来初始化 和上面的空数组区分开,以便知道何时添加了第一个元素 用来区别无参构造和有参构造初始容量为0创建的空数组
	// 无参构造创建时的空数组
	private static final Object[] DEFAULT_EMPTY_ELEMENTDATA = {};

	// 创建一个不被序列化的变量 用来存放数据
	transient Object[] elementData;

	// 记录数字的大小
	private int size;

	// arraylist 继承AbstractList 中的变量 用来在线程不安全的情况下记录修改次数
	// ,如果对象的modcount和迭代器中modcount不一致则会抛出
	// ConcurrentModificationException 并发修改异常 Fail-Fast快速失败机制
	protected transient int modCount = 0;

	// 有参构造 创建一个初始容量为initialCapacity值 的大小
	public OverrideArrayList(int initialCapacity) {
		// 如果参数值大于0 把elementData数组的长度变为initialCapacity
		if (initialCapacity > 0) {
			this.elementData = new Object[initialCapacity];
		} else if (initialCapacity == 0) {
			// 空数组赋给elementData
			this.elementData = EMPTY_ELEMENTDATA;
		} else {
			// 抛出异常 输入的为无效值
			throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
		}
	}

	// 无参构造
	public OverrideArrayList() {
		// 空数组赋给elementData 所以用无参构造新创建的arraylist数组容量为0
		this.elementData = DEFAULT_EMPTY_ELEMENTDATA;
	}

	// 有参构造 把传进来的集合 按照迭代器顺序存入到arraylist数组中
	public OverrideArrayList(Collection<? extends E> c) {
		elementData = c.toArray();// 把集合中的数据按迭代器输出顺序存放在elementData数组中
		// 如果传进来的集合长度不为0
		if ((size = elementData.length) != 0) {
			// 如果传进来的集合不是object类型 复制原数组到elementData中
			if (elementData.getClass() != Object[].class) {
				Arrays.copyOf(elementData, size, Object[].class);
			}
		} else {
			// 否则就为空数组
			elementData = EMPTY_ELEMENTDATA;
		}
	}

	// 修改容量为实际容量(数组中有空位,把空位消除)
	public void trimToSize() {
		// 修改一次
		modCount++;
		// 如果数组的长度大于实际的大小
		if (elementData.length > size) {
			// 如果实际大小为0,这返回空数组,如果实际大小不为0 则复制一个实际大小长度的数组给elementData
			elementData = (size == 0 ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size));
		}

	}

	// 如果需要 就增大 最小容量来保证所有数据能放下
	public void ensureCapacity(int minCapacity) {
		// 最小膨胀量 如果是有参构造创建的容量 则最小膨胀量0, 如果是无参构造创建的Arraylist则最小膨胀量为10(默认容量)
		int minExpand = (elementData != DEFAULT_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
		// 如果传进来的最小容量大于最小膨胀量
		if (minCapacity > minExpand) {
			// 确认容量
			ensureExplicitCapacity(minCapacity);
		}

	}

	// 用来确认容量 是否需要扩容
	private void ensureExplicitCapacity(int minCapacity) {
		modCount++;
		// 如果最小容量大于数组的长度 则扩容
		if (minCapacity > elementData.length) {
			// 扩容
			grow(minCapacity);
		}
	}

	// 定义最大的容量为int的最大值减8
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

	// 扩容
	private void grow(int minCapacity) {
		// 定义一个容量来存放旧数组的长度
		int oldCapacity = elementData.length;
		// 扩容后的新容量 为 旧容量加上旧容量右移一位(除以2取整) 换算后为旧容量的1.5倍
		int newCapacity = oldCapacity + (oldCapacity >> 1);
		// 如果扩容出来的容量任然不够 则把传进来的容量赋值给新容量
		if (newCapacity < minCapacity) {
			newCapacity = minCapacity;
		}
		// 如果扩容出来的新容量大于最大容量 则调用巨大容量得方法
		if (newCapacity - MAX_ARRAY_SIZE > 0) {
			newCapacity = hugeCapacity(minCapacity);
		}
		// 复制一个容量为newCapacity的新数组并把elementData的元素存进去 来替换旧的elementData
		elementData = Arrays.copyOf(elementData, newCapacity);
	}

	// 巨大(胡歌)容量的方法
	private static int hugeCapacity(int minCapacity) {
		// 如果扩容时 minCapacity大于int最大值,最高位会变为1,转化为10进制就是负数,就会报内存溢出错误
		if (minCapacity < 0) {
			// 内存溢出 overflow
			throw new OutOfMemoryError();
		}
		// 返回最大者
		return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
	}

	// 确保容量够
	private void ensureCapacityInternal(int minCapacity) {
		ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
	}

	// 判断是由无参构造创建的数组,还是有参构造创建的数组
	private static int calculateCapacity(Object[] elementData, int minCapacity) {
		// 如果是由无参构造创建的,返回10和最小容量的最大值 这就是为什么无参构造在第一次添加数据时的初始容量为10
		if (elementData == DEFAULT_EMPTY_ELEMENTDATA) {
			return Math.max(DEFAULT_CAPACITY, minCapacity);
		}
		// 如果不是,直接返回最小容量
		return minCapacity;
	}

	// 获取集合中元素的个数
	public int size() {
		return size;
	}

	// 判断是否为空集合
	public boolean isEmpty() {
		return size == 0;
	}

	// 判断是否包含此元素
	public boolean contains(Object o) {
		// 大于等于0,表示有次元素
		return indexOf(o) >= 0;
	}

	// 返回此元素第一次出现的下标,如果没有此元素则返回-1
	public int indexOf(Object o) {
		// 判断传进来的是否为null
		if (o == null) {
			for (int i = 0; i < size; i++) {
				// 即使有泛型约束,也可以添加null元素
				if (elementData[i] == null) {
					return i;
				}
			}
		} else {
			for (int i = 0; i < size; i++) {
				// 非空才能用equal方法
				if (o.equals(elementData[i])) {
					return i;
				}
			}
		}

		// 没找到返回-1
		return -1;
	}

	// 查找最后一次出现此元素的位置
	public int lastIndexOf(Object o) {
		// 判断传进来的是否为空
		if (o == null) {
			for (int i = 0; i < size; i++) {
				if (elementData[i] == null) {
					return i;
				}
			}
		} else {
			// 从最后一位开始查找,找到返回下表
			for (int i = size - 1; i >= 0; i--) {
				if (o.equals(elementData[i])) {
					return i;
				}
			}
		}

		// 没找到返回-1
		return -1;
	}

	// 复制数组
	public Object clone() {
		try {
			// 创建数组 v 用来复制
			OverrideArrayList<?> v = (OverrideArrayList<?>) super.clone();
			// 调用方法复制,浅克隆
			v.elementData = Arrays.copyOf(elementData, size);
			v.modCount = 0;
			return v;
		} catch (CloneNotSupportedException e) {
			// 如果没有实现cloneable就会抛异常
			throw new InternalError();
		}
	}

	// 返回一个复制的数组,从第一个元素到最后一个元素
	public Object[] toArray() {
		return Arrays.copyOf(elementData, size);
	}

	@SuppressWarnings("unchecked")
	public <T> T[] toArray(T[] a) {
		if (a.length < size) {
			// 返回一个指定类型的数组
			return (T[]) Arrays.copyOf(elementData, size, a.getClass());
		}
		// 把所有elementData的元素复制到a中
		System.arraycopy(elementData, 0, a, 0, size);
		// a数组下标size为null
		if (a.length > size) {
			a[size] = null;

		}
		return a;
	}

	// 获取指定下标的元素
	//数组的get set 快
	
   public E get(int index) {
		// 检查是否越界
		rangeCheck(index);
		return elementData(index);
	}

	E elementData(int index) {
		// TODO Auto-generated method stub
		return (E) elementData[index];
	}

	private void rangeCheck(int index) {
		if (index >= size) {
			// 下标越界
			throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
		}

	}

	// 返回错误信息
	private String outOfBoundsMsg(int index) {
		return "Index:" + index + ",Size:" + size;
	}

	// set赋值 返回旧的值
	public E set(int index, E element) {
		// 判断是否越界
		rangeCheck(index);
		// 拿到旧的值
		E oldValue = elementData(index);
		// 用新的值覆盖旧的值
		elementData[index] = element;
		// 返回旧的值
		return oldValue;
	}

	// 增加元素
	public boolean add(E e) {
		// 此方法调用calculateCapacity(计算容量)
		/*
		 * 如果是无参构造创建的数组,第一次添加元素则容量会判断传进来的容量和10比较,返回最大值, 有参构造创建则直接返回size+1
		 * 在调用ensureExplicitCapacity(int minCapacity) 然后modcount++
		 * 在判断传进来的容量与elementData.length比较 不够则扩容调用grow() 无参 的 第一次添加元素
		 * minCapacity=10 elementData.length=0 int oldCapacity =
		 * elementData.length =0; int newCapacity = oldCapacity + (oldCapacity
		 * >> 1); 0 = 0 + 0 if (newCapacity - minCapacity < 0) 0 10 newCapacity
		 * = minCapacity; 把 10赋给 newCapacity if (newCapacity - MAX_ARRAY_SIZE >
		 * 0) newCapacity = hugeCapacity(minCapacity); //复制出一个长度为10的数组出来
		 * elementData = Arrays.copyOf(elementData, newCapacity);
		 * 
		 */

		ensureCapacityInternal(size + 1);
		// 把元素添加到最后一位 size+1
		elementData[size++] = e;
		return true;
	}

	// 在指定位置插入元素
	public void add(int index, E element) {
		// 检查下标是否越界
		rangeCheckForAdd(index);
		// 判断是否能够装得下
		ensureCapacityInternal(size + 1);
		/*
		 * 涉及到数组扩容,复制数组所以效率慢
		 * 数组复制 第一个值 原数组 第二个值 从什么位置开始赋值 第三个值 赋值到新的数组中 第四个值 从什么位置开始接收 第五个值 复制的长度
		 */

		System.arraycopy(element, index, element, index + 1, size - index);
		// 把插进来的值赋给新数组
		elementData[index] = element;
		// size+1
		size++;
	}

	// 检查下标是否越界
	private void rangeCheckForAdd(int index) {
		if (index > size || index < 0) {
			throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
		}
	}

	// 根据下标删除元素
	public E remove(int index) {
		rangeCheck(index);
		// 找到要删除的元素
		E oldValue = elementData(index);
		// 判断删除的元素是否是最后一个元素
		int numMoved = size - index - 1;
		if (numMoved > 0) {
			// 复制出一个数组
			//涉及到数组扩容,复制数组所以效率慢
			System.arraycopy(elementData, index + 1, elementData, index, numMoved);

		}
		// 把新数组的最后一位变为null size-1
		elementData[--size] = null;
		return oldValue;
	}

	// 删除出现的第一个元素 如果存在
	public boolean remove(Object o) {
		// 判断传进来是否为null
		if (o == null) {
			// 遍历数组 查找是否有null元素
			for (int i = 0; i < elementData.length; i++) {
				if (elementData[i] == null) {
					// 删除元素
					fastRemove(i);
					// 返回true
					return true;
				}
			}
		} else {
			for (int i = 0; i < elementData.length; i++) {
				// 查找是否有 o元素相同的元素
				if (o.equals(elementData[i])) {
					// 删除第一次出现的位置
					fastRemove(i);
					return true;
				}
			}
		}
		// 没找到则返回false
		return false;
	}

	// 根据下边删除元素
	private void fastRemove(int i) {
		modCount++;// 被修改次数加1
		int numMoved = size - 1 - i;// 计算出要复制的个数
		if (numMoved > 0) { // 大于0表示不是最后一位 等于0表示是删除最后一位
			// 复制数组
			System.arraycopy(elementData, i + 1, elementData, i, numMoved);

		}
		elementData[--size] = null;// 把下标为i的值设置为空

	}

	public void clear() {
		modCount++;// 修改次数加1
		for (int i = 0; i < elementData.length; i++) {
			// 将所有元素赋值为null
			elementData[i] = null;

		}
		// size设置为0
		size = 0;

	}

	// 将指定集合的迭代输出顺序添加到数组的末尾
	public boolean addAll(Collection<? extends E> c) {
		// 返回按迭代器输出顺序的数组
		Object[] array = c.toArray();
		int length = array.length;
		ensureCapacityInternal(size + length);// 让其扩容 并且modcount+1
		// 赋值出新的数组 把传进来的集合添加进去
		System.arraycopy(array, 0, elementData, size, length);
		size += length;// size变大

		return length != 0;

	}

	public boolean addAll(int index, Collection<? extends E> c) {
		rangeCheckForAdd(index);// 检查下标是否越界

		Object[] array = c.toArray();
		int length = array.length;
		ensureCapacityInternal(size + length);
		// 看移动的位数
		int numMoved = size - length;
		// 如果小于0 表示之前的数组不用动
		if (numMoved > 0) {
			System.arraycopy(elementData, index, elementData, index + length, numMoved);
		}
		// 把传进来的数组加进去
		System.arraycopy(array, 0, elementData, index, length);

		size += length;// 数组长度变大

		return length != 0;
	}

	protected void removeRange(int fromIndex, int toIndex) {
		modCount++;// 修改次数加1
		// 移动的位数
		int numMoved = size - toIndex;
		System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);
		// 新数组的大小
		int newSize = size - (toIndex - fromIndex);
		// 把新数组的大小 到原数组大小之间的值变为null
		for (int i = newSize; i < size; i++) {
			elementData[i] = null;
		}
		// size变小
		size = newSize;

	}

	public boolean removeAll(Collection<?> c) {
		// 判断传进来的集合是否为null 如果为空则抛空指针异常
		Objects.requireNonNull(c);
		// 返回是否删除成功
		return batchRemove(c, false);

	}

	// 删除元素
	private boolean batchRemove(Collection<?> c, boolean b) {
		// 创建一个新数组来装原来的elementDate
		final Object[] elementDate = this.elementData;
		// 变量 r w
		int r = 0, w = 0;
		boolean mondify = false;
		try {
			// 遍历数组
			for (; r < size; r++) {
				/*
				 * 如果b为false 如果找到了要删除的元素 就不加入到新数组中 把不相同的元素添加到新数组中
				 */
				/*
				 * 如果b为true 则把相同的元素添加到集合中 如果没有相同则w=0 在后面把elementDate变为null
				 */
				if (c.contains(elementDate[r]) == b) {
					// 把不包含的元素覆盖原数组 w为新数组元素的个数
					elementDate[w++] = elementDate[r];
				}
			}
		} finally {
			// 出异常可能会导致的结果
			// if (r != size) {
			// System.arraycopy(elementData, r,
			// elementData, w,
			// size - r);
			// w += size - r;
			// }

			// 如果w!=size 则表示有元素被删除了
			if (w != size) {
				// 把下标w以及w后面的元素赋值为null
				for (int i = w; i < size; i++) {
					elementDate[i] = null;
				}
				// 记录修改次数
				modCount += size - w;
				// size变为w
				size = w;
				// 修改状态为成功
				mondify = true;
			}

		}

		return mondify;
	}

	// 修改成功返回ture 如果两个数组一模一样则返回false
	// 只保留c中的元素
	public boolean retainAll(Collection<?> c) {
		// 判断传进来的集合是否为null 如果为空则抛空指针异常
		Objects.requireNonNull(c);

		return batchRemove(c, true);

	}

	// 写入流
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
		// 预期修改次数
		int expectedModCount = modCount;
		s.defaultWriteObject();

		// Write out size as capacity for behavioural compatibility with clone()
		s.writeInt(size);

		// 以适当的顺序写出所有元素。
		for (int i = 0; i < size; i++) {
			s.writeObject(elementData[i]);
		}
		// 如果预期修改次数不等于修改次数 则抛并发修改异常
		if (modCount != expectedModCount) {
			throw new ConcurrentModificationException();
		}
	}

	// 读入流
	private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
		elementData = EMPTY_ELEMENTDATA;

		// Read in size, and any hidden stuff
		s.defaultReadObject();

		// Read in capacity
		s.readInt(); // ignored

		if (size > 0) {
			// be like clone(), allocate array based upon size not capacity
			int capacity = calculateCapacity(elementData, size);
			// SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class,
			// capacity);
			ensureCapacityInternal(size);

			Object[] a = elementData;
			// Read in all elements in the proper order.
			for (int i = 0; i < size; i++) {
				a[i] = s.readObject();
			}
		}
	}

	// 从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
	public ListIterator<E> listIterator(int index) {
		if (index < 0 || index > size)
			throw new IndexOutOfBoundsException("Index: " + index);
		return new ListItr(index);
	}

	// 返回列表中的列表迭代器(按适当的顺序)。
	public ListIterator<E> listIterator() {
		return new ListItr(0);
	}

	// 以正确的顺序返回该列表中的元素的迭代器。
	public Iterator<E> iterator() {
		return new Itr();
	}

	private class Itr implements Iterator<E>{
           int cursor;//记录下标
           int lastRet = -1;//记录最后一次修改的下标
		  int expectedModCount = modCount;
		  
		  Itr(){}//无参构造
		  
	
		public boolean hasNext() {
			//判断是否是最后一个元素
			return cursor!=size;
		}

		
		public E next() {
			//检查是否并发异常
			checkForComodification();
			//
			int i=cursor;
			if(i >= size){
				throw new NoSuchElementException();
			}
			//把elementData赋值给新创建的数组
			Object[] elementData=OverrideArrayList.this.elementData;
			if(i>elementData.length){
				
				throw new ConcurrentModificationException();
				
			}
			//指针向后移一位
			cursor=i+1;
			//返回当前元素
			return (E)elementData[lastRet=i];
		}
         
		//删除元素
		 public void remove() {
	            if (lastRet < 0)
	                throw new IllegalStateException();
	            checkForComodification();

	            try {
	            	//删除当前元素
	                OverrideArrayList.this.remove(lastRet);
	                //cursor 向后移一位
	                cursor = lastRet;
	                //把lastRet重新赋给-1
	                lastRet = -1;
	                //让其不出现并发修改异常
	                expectedModCount = modCount;
	            } catch (IndexOutOfBoundsException ex) {
	                throw new ConcurrentModificationException();
	            }
	        }

		private void checkForComodification() {
			if(expectedModCount != modCount){
				throw new  ConcurrentModificationException();
			}
			
			
		}
		  
	}
		
      private class ListItr extends Itr implements ListIterator<E> {
		        ListItr(int index) {
		            super();
		            cursor = index;
		        }

				@Override
				public boolean hasPrevious() {
					// TODO Auto-generated method stub
					return false;
				}

				@Override
				public E previous() {
					// TODO Auto-generated method stub
					return null;
				}

				@Override
				public int nextIndex() {
					// TODO Auto-generated method stub
					return 0;
				}

				@Override
				public int previousIndex() {
					// TODO Auto-generated method stub
					return 0;
				}

				@Override
				public void set(E e) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void add(E e) {
					// TODO Auto-generated method stub
					
				}
		  
		  
	  }
	

	
	

}

积累点滴,做好自己~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值