Java学习笔记程序员

Java Collection框架 - ArrayList

2017-03-09  本文已影响185人  xiedacon

Java Collection框架 - ArrayList

基于jdk1.8

简介

ArrayList是基于数组实现的动态数组,不是线程安全

时间复杂度:

数据结构

先看下ArrayList的数据结构:

ArrayList数据结构

ArrayList的数据结构很简单,就是一个数组跟一个size属性作为尾指针

主要属性与方法列表

//代表ArrayList默认容量 10
DEFAULT_CAPACITY : int
//内部数组
elementData : Object[]
//容量
size : int
//最大容量 Integer.MAX_VALUE - 8
MAX_ARRAY_SIZE : int

trimToSize() : void
ensureCapacity(int) : void
size() : int
isEmpty() : boolean
contains(Object) : boolean
indexOf(Object) : int
lastIndexOf(Object) : int
clone() : Object
toArray() : Object[]
toArray(T[]) : T[]
get(int) : E
set(int, E) : E
add(E) : boolean
add(int, E) : void
remove(int) : E
remove(Object) : boolean
clear() : void
addAll(Collection<? extends E>) : boolean
addAll(int, Collection<? extends E>) : boolean
removeAll(Collection<?>) : boolean
retainAll(Collection<?>) : boolean
listIterator(int) : ListIterator<E>
listIterator() : ListIterator<E>
subList(int, int) : List<E>
sort(Comparator<? super E>) : void

主要代码分析

  1. 查找

ArrayList提供了get(int index)用于读取数组中的元素。由于ArrayList使用数组实现,所以可以直接使用下标来获取元素

  public E get(int index) {
      rangeCheck(index);

      return elementData(index);
  }

  E elementData(int index) {
      return (E) elementData[index];
  }
  1. 增加

ArrayList提供了add(E e)add(int index, E element)addAll(Collection<? extends E> c)addAll(int index, Collection<? extends E> c)四个方法来添加元素

  1. 修改

ArrayList提供了set(int index, E element)方法来修改指定位置的元素

  1. 删除

ArrayList提供了remove(int index)remove(Object o)removeAll(Collection<?> c)retainAll(Collection<?> c)四个方法来删除元素

  1. 扩增

ArrayList提供了ensureCapacity(int minCapacity)ensureCapacityInternal(int minCapacity)两个方法供其他方法调用,用于扩增容量。这两个方法都依赖ensureExplicitCapacity(int minCapacity)方法,ensureExplicitCapacity(int minCapacity)方法又依赖grow(int minCapacity)方法

  public void ensureCapacity(int minCapacity) {
      int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
          // any size if not default element table
          ? 0
          // larger than default for default empty table. It's already
          // supposed to be at default size.
          : DEFAULT_CAPACITY;

      if (minCapacity > minExpand) {
          ensureExplicitCapacity(minCapacity);
      }
  }

  private void ensureCapacityInternal(int minCapacity) {
      if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
          minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
      }

      ensureExplicitCapacity(minCapacity);
  }

  private void ensureExplicitCapacity(int minCapacity) {
      modCount++;

      // overflow-conscious code
      if (minCapacity - elementData.length > 0)
          grow(minCapacity);
  }

  private void grow(int minCapacity) {
      // overflow-conscious code
      int oldCapacity = elementData.length;
      //计算新的数组容量,以1.5倍扩容
      //1.5倍是通过测试得到的一个最佳值
      //以1.5倍扩容。既不会消耗太多性能,也不会消耗太多内存
      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);
  }
  1. 迭代器

ArrayList实现了ItrListItr两个迭代器。ArrayList的迭代器能在遍历的同时添加或删除元素,是由于在这两个方法中修改了迭代器的expectedModCount记录

  public void remove() {
      if (lastRet < 0)
          throw new IllegalStateException();
      checkForComodification();

      try {
          ArrayList.this.remove(lastRet);
          cursor = lastRet;
          lastRet = -1;
          //修改记录
          expectedModCount = modCount;
      } catch (IndexOutOfBoundsException ex) {
          throw new ConcurrentModificationException();
      }
  }

  public void add(E e) {
      checkForComodification();

      try {
          int i = cursor;
          ArrayList.this.add(i, e);
          cursor = i + 1;
          lastRet = -1;
          //修改记录
          expectedModCount = modCount;
      } catch (IndexOutOfBoundsException ex) {
          throw new ConcurrentModificationException();
      }
  }

总结

  1. ArrayList的默认初始容量为10
  2. ArrayList以1.5倍扩容
上一篇 下一篇

猜你喜欢

热点阅读