ArrayList

作者: Jokerone_ | 来源:发表于2017-03-24 20:21 被阅读0次

    ArrayList以数组的形式实现,顺序插入、查找快,插入、删除较慢(==寻址容易,插入删除困难==)
    ArrayList的基本元素:

    元素 作用
    private transient Object[] elementData; ArrayList是基于数组的一个实现,elementData就是底层的数组
    private int size; ArrayList里面元素的个数,这里要注意一下,size是按照调用add、remove方法的次数进行自增或者自减的,所以add了一个null进入ArrayList,size也会加1

    四个关注点在ArrayList上的答案

    关注点 结论
    ArrayList是否允许空 允许
    ArrayList是否允许重复数据 允许
    ArrayList是否有序 有序
    ArrayList是否线程安全 非线程安全

    ArrayList的优点:

    1. ArrayList底层以数组实现,是一种随机访问模式,再加上它实现了RandomAccess接口,因此查找也就是get的时候非常快
    2. ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已
      ArrayList的缺点:
    3. 删除元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能
    4. 插入元素的时候,涉及到一次元素复制,如果要复制的元素很多,那么就会比较耗费性能

    因此,==ArrayList比较适合顺序添加、随机访问的场景==。

    注意两个问题:

    1. ArrayList和Vector的区别
    2. 为什么ArrayList的elementData是用transient修饰的?
    1、 容器默认大小为10,位置不够了自动扩增,每次增加当前长度的一半;(扩增时用Arrays.copyOf进行扩增)
    2、 数组容量扩增到Integer.MAX_VALUE-8的时候,就会开始限制数组扩充,超过Integer.MAX_VALUE的时候,抛内存溢出异常;
    3、 clone是浅拷贝,List中的引用指向的还是相同数据;
    4、 线程不安全的;
    5、 迭代器中的expectedModCount和modCount:迭代器初始化时,会用modCount去初始化expectedModCount,在迭代器的操作中都要检查这两个值的等值性,不想等抛出ConcurrentModificationException异常表示当前List正在被修改,为什么呢?如下:
    List本身的add和remove操作时都会修改modCount的值,如果在迭代器循环迭代过程中调用了List本身的add和remove方法就会导致两个值不想等而抛出异常,而迭代器本身的remove则不会有这个问题,它会在remove完成后重新更新一遍expectedModCount保持两个值的等值性。
    6、 ListIterator和普通迭代器类似,只是多了双向迭代的功能;
    7、 ArrayList本身的sort其实是调用Arrays.sort传入比较器实现的
    

    ArrayList自定义源码如下:

    package com.hao.laker.study.javabase.source;
    
    import java.util.Arrays;
    
    /**
     * 自定义数组
     * Created by haojiahong on 17/3/1.
     */
    public class MyArrayList<E> {
        private int capacity = 10;
        private int size = 0;
        private Object[] tables;
    
        public MyArrayList() {
            tables = new Object[capacity];
        }
    
        public MyArrayList(int capacity) {
            this.capacity = capacity;
            tables = new Object[capacity];
        }
    
        public void add(E e) {
            if (size >= capacity) {
                enlargeCapacity();
            }
            tables[size] = e;
            size++;
        }
    
        public void remove(int index) {
            if (index >= size) {
                throw new RuntimeException("the " + index + " is out of bond");
            }
            for (int i = index; i < size - 1; i++) {
                tables[i] = tables[i + 1];
            }
            tables[size - 1] = null;//垃圾回收
            size--;
        }
    
        @SuppressWarnings("unchecked")
        public E get(int index) {
            if (index >= size) {
                throw new RuntimeException("the " + index + " is out of bond");
            }
            return (E) tables[index];
    
        }
    
        /**
         * 数组扩容方法
         */
        private void enlargeCapacity() {
            capacity = capacity * 3 / 2 + 1;
    //        Object[] newTables = new Object[capacity];
    //        System.arraycopy(tables, 0, newTables, 0, tables.length);
            Object[] newTables = Arrays.copyOf(tables, capacity);
            tables = newTables;
        }
    
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            for (int i = 0; i < size; i++) {
                sb.append(tables[i]).append(",");
            }
            if (size > 0) {
                sb.deleteCharAt(sb.length() - 1);
            }
            sb.append("]");
            return sb.toString();
        }
    
        public static void main(String[] args) {
            MyArrayList<Integer> myArrayList = new MyArrayList<>();
            //添加操作
            myArrayList.add(1);
            myArrayList.add(2);
            myArrayList.add(3);
            myArrayList.add(1);
            myArrayList.add(2);
            myArrayList.add(3);
            myArrayList.add(1);
            myArrayList.add(2);
            myArrayList.add(3);
            myArrayList.add(1);
            myArrayList.add(2);
            myArrayList.add(3);
            System.out.println(myArrayList.toString());
            //删除操作
            myArrayList.remove(2);
            System.out.println(myArrayList.toString());
            //get操作
            System.out.println(myArrayList.get(0));
    
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:ArrayList

          本文链接:https://www.haomeiwen.com/subject/nrfqottx.html