Java基础 常见List实现原理 - ArrayList

来源:互联网 发布:一首歌火了网络歌手 编辑:程序博客网 时间:2024/06/15 19:47

1. ArrayList实现原理

ArrayList实现了List接口,底层使用数组保存所有元素。其基本操作就是对数组的操作。

public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

底层使用数组实现

 private transient Object[] elementData;

构造函数有三种:指定容量的空列表、初始容量为10的空列表、包含指定collection元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的。

  public ArrayList(int initialCapacity) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];    }public ArrayList() {        this(10);    } public ArrayList(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);    }
常用的方法

trimToSize():去掉预留元素位置ensureCapacity(int minCapacity):确保最小容量,实现逻辑为增加当前数组长度的一半,查看是否满足。isEmpty():判断数组长度是否为0contains(Object o):遍历数组,寻找元素lastIndexOf(Object o):倒序遍历数组,寻找最后的元素clone():通过数组的复制,实现arrayList克隆
存储功能:   ArrayList提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c)这些添加元素的方法。

// 用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素。  public E set(int index, E element) {        rangeCheck(index);        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }
// 将指定的元素添加到此列表的尾部。   public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }
// 将指定的元素插入此列表中的指定位置。  // 如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)。   public void add(int index, E element) {        rangeCheckForAdd(index);        ensureCapacityInternal(size + 1);  // Increments modCount!!        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        elementData[index] = element;        size++;    }

读取功能

 public E get(int index) {        rangeCheck(index);        return elementData(index);    }
删除功能
  public E remove(int index) {        rangeCheck(index);        modCount++;        E oldValue = elementData(index);        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // Let gc do its work        return oldValue;    }

Iterator和ListIterator主要区别有:

 public Iterator<E> iterator() {        return new Itr();    }    /**     * {@inheritDoc}     *     * <p>This implementation returns {@code listIterator(0)}.     *     * @see #listIterator(int)     */    public ListIterator<E> listIterator() {        return listIterator(0);    }

一、ListIterator有add()方法,可以向List中添加对象,而Iterator不能。

二、ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历。但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

三、ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator 没有此功能。

四、都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。


List的hashCode

//s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 
public int hashCode() {        int hashCode = 1;        for (E e : this)            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());        return hashCode;    }

Fail-Fast机制: 
ArrayList也采用了快速失败的机制,通过记录modCount参数来实现。在面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。














0 0
原创粉丝点击