• 【JDK】ArrayList集合 源码阅读


           这是博主第二次读ArrayList 源码,第一次是在很久之前了,当时读起来有些费劲,记得那时候HashMap的源码还是哈希表+链表的数据结构。

           时隔多年,再次阅读起来ArrayList感觉还蛮简单的,但是HashMap已经不是当年的HashMap了,所以下一篇会写HashMap的。

    起因:最近写了一个简单的文件校验方法,然后犯了一些比较低级的错误,博主的师兄在进行发布CR时,提出了一些建议,博主感觉羞愧难当,特此记录一下,诸君共勉。代码以及建议如下,已做脱敏处理:

        /**
         * 修改前
         */
        public String checkFileWithJveye() {
            //建立 sftp链接,获取目录下所有文件列表集合
            List<String> remoteSftpFileList = getRemoteSftpFileList();
            //获取服务器已下载列表文件集合(以XXX结尾的)
            List<String> localFileList = getLocalFileList();
            //已经存在的文件-remove
            for (int i = 0; i < remoteSftpFileList.size(); i++) {
                if (localFileList.contains(remoteSftpFileList.get(i))) {
                    remoteSftpFileList.remove(i);
                }
            }
            return remoteSftpFileList.toString();
        }
    /**
     * 师兄的批注:
     * Master @XXXX 大约 6 小时之前
     *         不应该在循环内进行 list.remove(index) 操作,当remove一个元素之后,
     *         list会调整顺序,size() 会重新计算len,但是i还是原来的值,
     *         导致list有些值没有被循环到。推荐使用迭代器 list.iterator(),
     *         或者将返回的类型改为set,空间换时间,这样速度也能快些。
     * 讨论中师兄从源码方面解释了ArrayList使用的是遍历Remove,而HashSet直接通过Hash值进行Remove效率更高。
     */
    
    
        /**
         * 修改后
         */
        public String checkFileWithJveye2() {
            //建立 sftp链接,获取目录下所有文件列表集合
            Set<String> remoteSftpFiles = getRemoteSftpFileList();
            //获取服务器已下载列表文件集合(以XXX结尾的)
            Set<String> localFiles = getLocalFileList();
            //已经存在的文件-remove
            for (Iterator<String> it = remoteSftpFiles.iterator(); it.hasNext(); ) {
                String fileName = it.next();
                if (localFiles.contains(fileName)) {
                    it.remove();
                }
            }
            //返回未获取文件的列表
            return remoteSftpFiles.toString();
        }

           因此博主重读了ArrayList等源代码,都是复制的源代码,方便阅读,省去了很多年东西(本来东西也不多),只有简单的增删改,继承关系图如下:

    代码如下:

    import java.util.*;
    
    /**
     * ArrayList简单的增删改查
     * @param <E>
     */
    public class Bag<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
    
        /**
         * Default initial capacity.
         * 默认的初始化容量
         */
        private static final int DEFAULT_CAPACITY = 10;
    
        /**
         * Shared empty array instance used for empty instances.
         * EMPTY_CAPACITY
         */
        //private static final Object[] EMPTY_ELEMENTDATA = {};
    
        /**
         * Shared empty array instance used for default sized empty instances. We
         * distinguish(辨别,分清) this from EMPTY_ELEMENTDATA to know how much to inflate(增长) when
         * first element is added.
         * DEFAULT_CAPACITY
         */
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
        /**
         * The array buffer into which the elements of the ArrayList are stored.
         * The capacity of the ArrayList is the length of this array buffer. Any
         * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
         * will be expanded to DEFAULT_CAPACITY when the first element is added.
         *
         * non-private to simplify nested class access      非私有简化嵌套类的使用。
         */
        transient Object[] elementData;
    
        /**
         * The size of the ArrayList (the number of elements it contains).
         * 集合中元素的个数
         * @serial
         */
        private int size;
        /**
         * The maximum size of array to allocate.
         * Some VMs reserve some header words in an array.
         * Attempts to allocate larger arrays may result in
         * OutOfMemoryError: Requested array size exceeds VM limit
         * 最大容量
         */
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    
    
    
        /**
         * Constructs an empty list with an initial capacity of ten.
         * 初始化构造方法-这里只保留了一个
         */
        public Bag() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    
        /**
         * 增
         * Appends the specified element to the end of this list.
         * @param e element to be appended to this list
         * @return <tt>true</tt> (as specified by {@link Collection#add})
         */
        @Override
        public boolean add(E e) {
            // Increments modCount!!
            ensureCapacityInternal(size + 1);
            elementData[size++] = e;
            return true;
        }
        public void ensureCapacityInternal(int minCsap){
            minCsap=minCsap>=DEFAULT_CAPACITY?minCsap:DEFAULT_CAPACITY;
            if (minCsap - elementData.length > 0){
                grow(minCsap);
            }
    
        }
        /**
         * 查
         * Returns the element at the specified position in this list.
         * @param  index index of the element to return
         * @return the element at the specified position in this list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        @Override
        public E get(int index) {
            if (index >= size){
                throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size());
            }
    
    
            return elementData(index);
        }
        // Positional Access Operations
    
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
        /**
         * Increases the capacity to ensure that it can hold at least the
         * number of elements specified by(由。。。指定) the minimum capacity argument.
         *
         * @param minCapacity the desired minimum capacity
         */
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0){
                newCapacity = minCapacity;
            }
            if (newCapacity - MAX_ARRAY_SIZE > 0){
                newCapacity = hugeCapacity(minCapacity);
            }
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        private static int hugeCapacity(int minCapacity) {
            // overflow
            if (minCapacity < 0){
                throw new OutOfMemoryError
                        ("Required array size too large");
            }
            return (minCapacity > MAX_ARRAY_SIZE) ?
                    Integer.MAX_VALUE :
                    MAX_ARRAY_SIZE;
        }
    
    
        /**
         *删
         * Removes the element at the specified position in this list.
         * Shifts any subsequent elements to the left (subtracts one from their
         * indices).
         *
         * @param index the index of the element to be removed
         * @return the element that was removed from the list
         * @throws IndexOutOfBoundsException {@inheritDoc}
         */
        @Override
        public E remove(int index) {
            //验证index
            rangeCheck(index);
            E oldValue = elementData(index);
    
            int numMoved = size - index - 1;
            if (numMoved > 0){
                System.arraycopy(elementData, index+1, elementData, index, numMoved);
            }
            // clear to let GC do its work?
            elementData[--size] = null;
            return oldValue;
        }
        private void rangeCheck(int index) {
            if (index >= size){
                throw new IndexOutOfBoundsException("Index:+index+, Size: +size()");
            }
    
        }
    
        /**
         * 删
         * Removes the first occurrence of the specified element from this list,
         * if it is present.  If the list does not contain the element, it is
         * unchanged.  More formally, removes the element with the lowest index
         * <tt>i</tt> such that
         * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
         * (if such an element exists).  Returns <tt>true</tt> if this list
         * contained the specified element (or equivalently, if this list
         * changed as a result of the call).
         *
         * @param o element to be removed from this list, if present
         * @return <tt>true</tt> if this list contained the specified element
         */
        @Override
        public boolean remove(Object o){
            if(o==null){
                for (int i=0;i<elementData.length;i++){
                    if(elementData[i]==null){
                        fastRemove(i);
                        return true;
                    }
                }
            }else{
                for (int i=0;i<elementData.length;i++){
                    if(o.equals(elementData[i])){
                        fastRemove(i);
                        return true;
                    }
                }
    
            }
            return false;
        }
        /**
         * arrayCopy( arr1, 2, arr2, 5, 10);
         * 意思是;将arr1数组里从索引为2的元素开始, 复制到数组arr2里的索引为5的位置, 复制的元素个数为10个.
         */
        private void fastRemove(int index){
            int numMoved = size - index - 1;
            if (numMoved > 0){
                System.arraycopy(elementData, index+1, elementData, index, numMoved);
            }
            // clear to let GC do its work
            elementData[--size] = null;
        }
    
    
    
    
        /**
         * Returns the number of elements in this list.
         *
         * @return the number of elements in this list
         */
        @Override
        public int size() {
            return size;
        }
    
        /**
         * Returns <tt>true</tt> if this list contains no elements.
         *
         * @return <tt>true</tt> if this list contains no elements
         */
        @Override
        public boolean isEmpty() {
            return size == 0;
        }
    
    
    }
    
  • 相关阅读:
    mysql修改数据表名
    HDU 5742 It's All In The Mind (贪心)
    HDU 5752 Sqrt Bo (数论)
    HDU 5753 Permutation Bo (推导 or 打表找规律)
    HDU 5762 Teacher Bo (暴力)
    HDU 5754 Life Winner Bo (博弈)
    CodeForces 455C Civilization (并查集+树的直径)
    CodeForces 455B A Lot of Games (博弈论)
    CodeForces 455A Boredom (DP)
    HDU 4861 Couple doubi (数论 or 打表找规律)
  • 原文地址:https://www.cnblogs.com/the-fool/p/11054035.html
Copyright © 2020-2023  润新知