Depth java8 collection: ArrayList realization of the principle of

  I. Overview

  Come on, let's look at this a comment in the source code, we can extract some key information:

  Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is unsynchronized.)

  From this comment, we can see that ArrayList is a dynamic array, realized List interface and list all relevant methods, which allow the insertion of all elements, including null. Further, in addition to the ArrayList and Vector outside thread is not synchronized, substantially equal.

  Second, property

  // default size capacity

  private static final int DEFAULT_CAPACITY = 10;

  // empty array constants

  private static final Object[] EMPTY_ELEMENTDATA = {};

  // default empty array constant

  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

  // storage array elements from this ArrayList can be found in the underlying implementation is an Object array

  transient Object[] elementData;

  // number of elements contained in the array

  private int size;

  Maximum limit // array

  private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

  ArrayList property is very small, only these. One of the most important is the elementData, ArrayList all methods are built on elementData. Next, we look at some of the main ways it.

  Third, the method

  1, construction method

  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);

  }

  }

  public ArrayList() {

  this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

  }

  We can see from the constructor, by default, elementData empty array size is a 0 when we specify the initial size when the initial size becomes elementData we specify the initial size.

  2, get method

  public E get(int index) {

  rangeCheck (index);

  return elementData(index);

  }

  private void rangeCheck(int index) {

  if (index >= size)

  throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

  }

  E elementData(int index) {

  return (E) elementData[index];

  }

  Because ArrayList is the use of an array of structures is stored, so it get method is very simple, first determining if there is an out of bounds, then it is possible to obtain the element directly through the array subscripts, so get the time complexity is O (1).

  3, add method

  public boolean add(E e) {

  ensureCapacityInternal(size + 1); // Increments modCount!!

  elementData[size++] = e;

  return true;

  }

  public void add(int index, E element) {

  rangeCheckForAdd (index);

  ensureCapacityInternal(size + 1); // Increments modCount!!

  // Call a native of replication method, the starting position of the element index are moved back one

  System.arraycopy(elementData, index, elementData, index + 1, size - index);

  elementData[index] = element;

  size++;

  }

  private void ensureCapacityInternal(int minCapacity) {

  if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

  minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);

  }

  ensureExplicitCapacity(minCapacity);

  }

  private void ensureExplicitCapacity(int minCapacity) {

  modCount++;

  if (minCapacity - elementData.length > 0)

  grow(minCapacity);

  }

  ArrayList add method is also well understood, before inserting elements, it first checks whether the capacity is needed, and then adding elements to the array after the last element. In ensureCapacityInternal method, we can see, if and when elementData an empty array, it uses the default size to expansion. So, when creating ArrayList by no constructor parameters, its size is actually zero, only to use the time, only to create an array of size 10 through the grow method.

  The first method add complexity to O (1), although sometimes involve the expansion of the operation, but the number of expansion is very small, so this part of the time is negligible. If you are using the subject with the specified add method, the complexity is O (n), because it involves the movement of the elements in the array, this operation is very time consuming.

  4, set method

  public E set(int index, E element) {

  rangeCheck (index);

  E oldValue = elementData(index);

  elementData[index] = element;

  return oldValue;

  }

  The method set action is to replace the subscript index into Element element, with get very similar, so will not repeat, the degree of time complexity O (1).

  5, remove method

  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; // clear to let GC do its work

  return oldValue;

  }

  The subject method is very similar to the add and remove with the specified method, a method is invoked to move the system arraycopy elements, time complexity is O (n).

  6, grow method

  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);

  } Zhengzhou which hospital treatment of gynecological good http://www.120kdfk.com/

  grow method is used when the array expansion, from which we can see, ArrayList every time expansion is expanded 1.5 times, and then call copyOf method Arrays class, re-copy the elements to a new array to go.

  7, size method

  public int size() {

  return size;

  }

  size method is very simple, it is the size of direct return value, that is, returns the number of elements in the array, the time complexity is O (1). Here we must note, is not the actual size of the returned array.

  8, indexOf method and lastIndexOf

  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;

  }

  Action indexOf method is to return the first element is equal to the calibration value. It is traversed by comparing the value of each element of the array to find, its time complexity is O (n).

  LastIndexOf principle of like indexOf, but it is only starting from the back to find nothing.

  Vector

  Vector ArrayList many ways related to the same, but pay more of a synchronized to ensure thread safety. So that different points of Vector and ArrayList look at it.

  Vector one more attribute than ArrayList:

  protected int capacityIncrement;

  This property is used at the time of expansion, it represents a time expansion only expand capacityIncrement a space is sufficient. This attribute can be assigned to it by the constructor. First look at the constructor:

  public Vector(int initialCapacity, int capacityIncrement) {

  super();

  if (initialCapacity < 0)

  throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);

  this.elementData = new Object[initialCapacity];

  this.capacityIncrement = capacityIncrement;

  }

  public Vector(int initialCapacity) {

  this(initialCapacity, 0);

  }

  public Vector() {

  this(10);

  }

  From the constructor, we can see that the default size of the Vector is 10, and it is in the initialization of the array has been created, this is not the same as with ArrayList. Then look at the grow method:

  private void grow(int minCapacity) {

  // overflow-conscious code

  int oldCapacity = elementData.length;

  int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

  if (newCapacity - minCapacity < 0)

  newCapacity = minCapacity;

  if (newCapacity - MAX_ARRAY_SIZE > 0)

  newCapacity = hugeCapacity(minCapacity);

  elementData = Arrays.copyOf(elementData, newCapacity);

  }

  We can see from the grow process, newCapacity default is twice the oldCapacity, and when the value of capacityIncrement specified, newCapacity became oldCapacity + capacityIncrement.

  to sum up

  1, when the size of the created ArrayList 0; when added to the first element, for the first time expansion, the capacity of the default size of 10.

  2, ArrayList each expansion are 1.5 times the size of the array to the current expansion.

  3, the default size when Vector created 10.

  4, Vector expansion are each 2 times the size of the array to the current expansion. When specifying capacityIncrement, each expansion only increase capacityIncrement units of space in the original basis.

  5, add ArrayList and the Vector, get, size complexity of the method are O (1), the complexity of the remove method is O (n).

  6, ArrayList is non-thread-safe, Vector is thread-safe.

Guess you like

Origin www.cnblogs.com/djw12333/p/12067249.html