ArrayList-数组集合
来源:互联网 发布:node fs模块 编辑:程序博客网 时间:2024/06/05 03:19
ArrayList底层由数组实现,数组在java内存是连续片段,所以数组增删某元素时,删除元素后,需要将整个片段前移填补空缺,运行速度比较慢。 ArrayList,LinkedList相对区别 ArrayList:查询快,增删慢。 LinkedList:查询慢, 增删快。(只需要改变前后元素的指向)
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ private static final long serialVersionUID = 8683452581122892189L; //默认初始化容量 private static final int DEFAULT_CAPACITY = 10; //内部数据结构 数组 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. */ 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. */ transient Object[] elementData; // non-private to simplify nested class access //集合长度 private int size; //带容量的初始化 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; } //初始化集合 将其他集合元素并入该集合 public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } } public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); //取size大小的数组 } } //保证容量大小(内部结构是数组) 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); //保证集合容量 >= 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); //扩容 } /** * 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; /** * 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) //仍小于minCapacity,则将容量设为minCapacity newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //设为 Integer.MAX_VALUE // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); //返回新数组 } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } //返回集合长度 public int size() { return size; } //判断集合是否为空 public boolean isEmpty() { return size == 0; } //判断集合是否含有指定元素 public boolean contains(Object o) { return indexOf(o) >= 0; } //查询元素在集合的下标位置 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; //没有该元素 } /** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ 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; } //克隆一个新的集合 public Object clone() { try { ArrayList<?> v = (ArrayList<?>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } } //将集合转化为数组 public Object[] toArray() { return Arrays.copyOf(elementData, size); } //将集合转化为指定类型的数组 ****** // 1.当类型数组长度小于集合长度时 // 返回与集合相同长度的数组,元素与集合元素相同 // 2.当类型数组长度大于集合长度时, // 返回与类型数组相同长度的数组,元素与集合元素相同,但是超出部分的size下标元素为null @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } //返回指定下标的元素 查询快的原因 E elementData(int index) { return (E) elementData[index]; } //返回指定下标的元素 public E get(int index) { rangeCheck(index); return elementData(index); } //将指定位置的元素置为 element 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; } //将元素插入指定位置 public void add(int index, E element) { rangeCheckForAdd(index); //防止角标越界 //保证集合容量 ensureCapacityInternal(size + 1); // Increments modCount!! //将原数组从index下标开始的元素移动到index+1 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } //删除指定位置的元素 public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); //获取index角标的元素 int numMoved = size - index - 1; //删除后,需要移动的元素数量 if (numMoved > 0) //将index后的元素向前移动一位 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } //移除指定元素 public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { //遍历移除 //将下标为index的元素移除 并将index后的元素向前移动一格 fastRemove(index); return true; } } else { //同理 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } /* * Private remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; //需要移动的元素个数 if (numMoved > 0) //将index角标后的元素向前一格移动元素 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work } //清空集合 public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; //遍历 将元素都置为null size = 0; } //并入其他集合的所有元素 public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; //保证集合容量 ensureCapacityInternal(size + numNew); // Increments modCount //将a数组的元素copy到集合中,下标为size起,长度为numNew System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; } //在指定位置添加其他集合所有元素 public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; //需要添加的元素个数 ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; //需要移动的元素个数 if (numMoved > 0) //将原集合index角标后长度为numMoved 移动到index+numNew(插入角标+c集合个数)处 System.arraycopy(elementData, index, elementData, index + numNew, numMoved); //将集合c的元素添加到index角标起,长度为numNew(c集合长度) System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
0 0
- 数组/集合(ArrayList)/泛型
- ArrayList-数组集合
- ArrayList , Vector 数组集合
- 【集合】ArrayList数组列表类
- 集合框架1,数组集合ArrayList
- 数组和集合对象(三) ArrayList练习
- C#集合的概述、动态数组ArrayList
- 字符串数组转换为ArrayList集合
- 解决二维数组转为ArrayList集合问题
- Java基础知识_day09_(对象数组,ArrayList集合)
- Java 集合框架ArrayList 储存自定义数组
- 对象数组,集合,ArrayList,LinkedList,TreeSet,
- 集合--ArrayList
- 集合ArrayList
- ArrayList集合
- 集合 --- ArrayList
- ArrayList集合
- ArrayList集合
- poj3259 Wormholes
- mysql查询今天、昨天、本周、本月、上一月 、今年数据
- 排序算法
- 利用filter()滤掉非回数
- 【CS 20SI】TensorFlow for Deep Learning Research Lecture note 2: TensorFlow Ops
- ArrayList-数组集合
- 二分查找算法实现
- 站在讲台上的时候,我怕我会心虚
- 函数中的私有变量和特权方法
- Python调用OpenCV的接口
- <Effective Mordern C++>笔记:Item 1: Understand the template type deduction.
- ROS 学习系列 -- 树莓派编译安装完整版本ROS
- 利用锚点制作简单索引效果
- Android-Fragment(1)简单实现