• Java集合二ArrayList


    ArrayList####

      ArrayList是一个数组,相当于动态数组。容量能够动态增长,继承与AbstractList,实现了List,RandomAccess,Cloneable,io.Serializable接口。
      实现RandomAccess了,提供了随机访问功能。RandomAccess是Java中用来被List实现,为List提供快速访问功能的。ArrayList中,通过序号快速获取元素对象,这就是快速随机访问
      ArrayList支持序列化,能够通过序列化传输。

    遍历方式####

      1、迭代器iterator,底层调用的也会普通for
      2、增强for,底层还是会调用普通for
      3、普通for索引,并通过get()方法
      第三种方法速度最快,第一种最慢。

    源码解析####

    package java.util;
    
    import java.util.function.Consumer;
    import java.util.function.Predicate;
    import java.util.function.UnaryOperator;
    import jdk.internal.misc.SharedSecrets;
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        private static final long serialVersionUID = 8683452581122892189L;
    
        //默认值为10
        private static final int DEFAULT_CAPACITY = 10;
        private static final Object[] EMPTY_ELEMENTDATA = {};
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
        transient Object[] elementData; 
    	//集合的实际容量大小
        private int size;
    
        //默认容量的构造函数
        public ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
        }
    
        //默认值为10的构造函数
        public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    
        //包含Collection的构造函数
        public ArrayList(Collection<? extends E> c) {
    		//将集合c中的元素转换成数组存入elementData数组中
            elementData = c.toArray();
    		//判断数组elementData的长度是否不等于0
            if ((size = elementData.length) != 0) {
    			//elementData的长度不为0,再判断elementData的数据类型
                if (elementData.getClass() != Object[].class)
    				//如果elementData中数据类型不是Object[].class类,
    				//则复制elementData中的元素并转换为Object[].class类型,在赋值给elementData
                    elementData = Arrays.copyOf(elementData, size, Object[].class);
            } else {
    			//Collection为空
                this.elementData = EMPTY_ELEMENTDATA;
            }
        }
    
       // 将此 ArrayList 实例的容量调整为列表的当前大小。
       //modCount初始值为0
        public void trimToSize() {
            modCount++;
    		//如果集合的实际元素值小于集合的容量
    		//elementData数组是集合用来存放元素的
            if (size < elementData.length) {
    			//elementData = 
    			//如果size等于0,则将EMPTY_ELEMENTDATA数组赋值给elementData
    			//如果size不等于0,则重新复制数组并重新定义存储集合元素的数组大小
    			//(size == 0) ? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);
                elementData = (size == 0)
                  ? EMPTY_ELEMENTDATA
                  : Arrays.copyOf(elementData, size);
            }
        }
    
    	//如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 
        public void ensureCapacity(int minCapacity) {
            if (minCapacity > elementData.length
                && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
                     && minCapacity <= DEFAULT_CAPACITY)) {
                modCount++;
    			//grow()方法调用Arrays.copyOf()方法
    			//将集合中的元素复制重新传给elementData
                grow(minCapacity);
            }
        }
    
       
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
        private Object[] grow(int minCapacity) {
            return elementData = Arrays.copyOf(elementData,
                                               newCapacity(minCapacity));
        }
    
        private Object[] grow() {
            return grow(size + 1);
        }
    
        private int newCapacity(int minCapacity) {
            int oldCapacity = elementData.length;
    		//注意此处扩充capacity的方式是将其向右一位再加上原来的数,实际上是扩充了1.5倍
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity <= 0) {
                if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                    return Math.max(DEFAULT_CAPACITY, minCapacity);
                if (minCapacity < 0) // overflow
                    throw new OutOfMemoryError();
                return minCapacity;
            }
            return (newCapacity - MAX_ARRAY_SIZE <= 0)
                ? newCapacity
                : hugeCapacity(minCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE)
                ? Integer.MAX_VALUE
                : MAX_ARRAY_SIZE;
        }
    
    	//返回集合的大小
        public int size() {
            return size;
        }
    
        //判断集合是否为空
        public boolean isEmpty() {
            return size == 0;
        }
    
        //判断是否包含指定元素
        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }
    
        //判断指定元素索引值
        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;
        }
    
        //判断元素最后出现的索引值
        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;
        }
    
        //复制
        public Object clone() {
            try {
                ArrayList<?> v = (ArrayList<?>) 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(e);
            }
        }
    
        //转换为数组
        public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
        }
    
        @SuppressWarnings("unchecked")
        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;
        }
    
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        @SuppressWarnings("unchecked")
        static <E> E elementAt(Object[] es, int index) {
            return (E) es[index];
        }
    
        //获取指定索引值的元素
    	//get()方法是直接获取指定数组索引的元素,比iterator遍历更快
    	//iterator底层也是通过数组的索引获得数组元素
        public E get(int index) {
    		//判断索引是否在集合元素索引范围内?没找到源码
            Objects.checkIndex(index, size);
    		//返回指定索引的数组元素
            return elementData(index);
        }
    
    	//设置指定索引出的元素
        public E set(int index, E element) {
            Objects.checkIndex(index, size);
            E oldValue = elementData(index);
            elementData[index] = element;
            return oldValue;
        }
    
        private void add(E e, Object[] elementData, int s) {
            if (s == elementData.length)
                elementData = grow();
            elementData[s] = e;
            size = s + 1;
        }
    
        //添加元素到集合末尾
        public boolean add(E e) {
            modCount++;
            add(e, elementData, size);
            return true;
        }
    
        //将指定元素添加到指定索引
        public void add(int index, E element) {
            rangeCheckForAdd(index);
            modCount++;
            final int s;
            Object[] elementData;
            if ((s = size) == (elementData = this.elementData).length)
                elementData = grow();
            System.arraycopy(elementData, index,
                             elementData, index + 1,
                             s - index);
            elementData[index] = element;
            size = s + 1;
        }
    
    	//删除指定索引上的元素
    	//ArrayList删除元素都是通过设置为null等到垃圾回收机制回收
        public E remove(int index) {
            Objects.checkIndex(index, size);
    
            modCount++;
            E oldValue = elementData(index);
    
            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
    
            return oldValue;
        }
    
    	//移除ArrayList中首次出现的指定元素(如果存在)。
        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; // clear to let GC do its work
        }
    
        //清空元素
        public void clear() {
            modCount++;
            final Object[] es = elementData;
            for (int to = size, i = size = 0; i < to; i++)
                es[i] = null;
        }
    
        //将另一个集合添加到这个集合中
        public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();
            modCount++;
            int numNew = a.length;
            if (numNew == 0)
                return false;
            Object[] elementData;
            final int s;
            if (numNew > (elementData = this.elementData).length - (s = size))
                elementData = grow(s + numNew);
            System.arraycopy(a, 0, elementData, s, numNew);
            size = s + numNew;
            return true;
        }
    
        //从指定的位置开始,将指定 collection 中的所有元素插入到此列表中
        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
    
            Object[] a = c.toArray();
            modCount++;
            int numNew = a.length;
            if (numNew == 0)
                return false;
            Object[] elementData;
            final int s;
            if (numNew > (elementData = this.elementData).length - (s = size))
                elementData = grow(s + numNew);
    
            int numMoved = s - index;
            if (numMoved > 0)
                System.arraycopy(elementData, index,
                                 elementData, index + numNew,
                                 numMoved);
            System.arraycopy(a, 0, elementData, index, numNew);
            size = s + numNew;
            return true;
        }
    
        //移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
        protected void removeRange(int fromIndex, int toIndex) {
            if (fromIndex > toIndex) {
                throw new IndexOutOfBoundsException(
                        outOfBoundsMsg(fromIndex, toIndex));
            }
            modCount++;
            shiftTailOverGap(elementData, fromIndex, toIndex);
        }
        private void shiftTailOverGap(Object[] es, int lo, int hi) {
            System.arraycopy(es, hi, es, lo, size - hi);
            for (int to = size, i = (size -= hi - lo); i < to; i++)
    			//将范围内的元素设置为null
                es[i] = null;
        }
    
        //检查索引是否越界
        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;
        }
        private static String outOfBoundsMsg(int fromIndex, int toIndex) {
            return "From Index: " + fromIndex + " > To Index: " + toIndex;
        }
    
        //删除集合中包含集合c中的元素,删除交集
        public boolean removeAll(Collection<?> c) {
            return batchRemove(c, false, 0, size);
        }
    
    	//删除集合中不包含集合c中的元素,求交集
        public boolean retainAll(Collection<?> c) {
            return batchRemove(c, true, 0, size);
        }
    	
        boolean batchRemove(Collection<?> c, boolean complement,
                            final int from, final int end) {
            Objects.requireNonNull(c);
            final Object[] es = elementData;
            final boolean modified;
            int r;
            // Optimize for initial run of survivors
            for (r = from; r < end && c.contains(es[r]) == complement; r++)
                ;
            if (modified = (r < end)) {
                int w = r++;
                try {
                    for (Object e; r < end; r++)
                        if (c.contains(e = es[r]) == complement)
                            es[w++] = e;
                } catch (Throwable ex) {
                    // Preserve behavioral compatibility with AbstractCollection,
                    // even if c.contains() throws.
                    System.arraycopy(es, r, es, w, end - r);
                    w += end - r;
                    throw ex;
                } finally {
                    modCount += end - w;
                    shiftTailOverGap(es, w, end);
                }
            }
            return modified;
        }
    
         //将ArrayList的“容量,所有的元素值”都写入到输出流中 
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            // Write out element count, and any hidden stuff
            int expectedModCount = 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 != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    
        //先将ArrayList的“大小”读出,然后将“所有的元素值”读出
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
    
            // Read in size, and any hidden stuff
            s.defaultReadObject();
    
            // Read in capacity
            s.readInt(); // ignored
    
            if (size > 0) {
                // like clone(), allocate array based upon size not capacity
                SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
                Object[] elements = new Object[size];
    
                // Read in all elements in the proper order.
                for (int i = 0; i < size; i++) {
                    elements[i] = s.readObject();
                }
    
                elementData = elements;
            } else if (size == 0) {
                elementData = EMPTY_ELEMENTDATA;
            } else {
                throw new java.io.InvalidObjectException("Invalid size: " + size);
            }
        }
    
        //增强for其实调用的还是普通for方法
        public void forEach(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            final int expectedModCount = modCount;
            final Object[] es = elementData;
            final int size = this.size;
            for (int i = 0; modCount == expectedModCount && i < size; i++)
                action.accept(elementAt(es, i));
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    
        public boolean removeIf(Predicate<? super E> filter) {
            return removeIf(filter, 0, size);
        }
    
        /**
         * Removes all elements satisfying the given predicate, from index
         * i (inclusive) to index end (exclusive).
         */
        boolean removeIf(Predicate<? super E> filter, int i, final int end) {
            Objects.requireNonNull(filter);
            int expectedModCount = modCount;
            final Object[] es = elementData;
            // Optimize for initial run of survivors
            for (; i < end && !filter.test(elementAt(es, i)); i++)
                ;
            // Tolerate predicates that reentrantly access the collection for
            // read (but writers still get CME), so traverse once to find
            // elements to delete, a second pass to physically expunge.
            if (i < end) {
                final int beg = i;
                final long[] deathRow = nBits(end - beg);
                deathRow[0] = 1L;   // set bit 0
                for (i = beg + 1; i < end; i++)
                    if (filter.test(elementAt(es, i)))
                        setBit(deathRow, i - beg);
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                expectedModCount++;
                modCount++;
                int w = beg;
                for (i = beg; i < end; i++)
                    if (isClear(deathRow, i - beg))
                        es[w++] = es[i];
                shiftTailOverGap(es, w, end);
                return true;
            } else {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return false;
            }
        }
    
        @Override
        public void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(operator);
            final int expectedModCount = modCount;
            final Object[] es = elementData;
            final int size = this.size;
            for (int i = 0; modCount == expectedModCount && i < size; i++)
                es[i] = operator.apply(elementAt(es, i));
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            modCount++;
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public void sort(Comparator<? super E> c) {
            final int expectedModCount = modCount;
            Arrays.sort((E[]) elementData, 0, size, c);
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            modCount++;
        }
    
        void checkInvariants() {
            // assert size >= 0;
            // assert size == elementData.length || elementData[size] == null;
        }
    }
    
    
  • 相关阅读:
    移动桌面文件
    软件项目经理素质能力的必备要求
    如何管理时间
    《明日歌》
    浏览网页出现iexplore.exe应用程序错误为:"0x03e620b0"指令引用的"0x00000000"内存.该内存不能为"read"?
    css网站布局学习笔记
    因为爱,人生除了理智,还有情感!
    35岁之前成功的12条黄金法则
    VS2005中没有DataGrid控件的解决方案
    先装VS2005再装IIS,出现访问IIS元数据库失败解决方案
  • 原文地址:https://www.cnblogs.com/changzuidaerguai/p/8853429.html
Copyright © 2020-2023  润新知