源码分析——new ArrayList() 和 new ArrayList(0)区别
2022-03-22 19:02
148 查看
1、分析
初始化
/** * 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 = {}; /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
/** * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ 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); } }
都是初始化为一个空的Object[],看着没差别,实际主要区别在扩容上
扩容
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; /** * Increases the capacity of this <tt>ArrayList</tt> instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ 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); }
ArrayList():ensureCapacity方法计算出来的minCapacity是10
ArrayList(0):ensureCapacity方法计算出来的minCapacity是0
/** * 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) 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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
扩容规则:newCapacity = oldCapacity + (oldCapacity / 2),即扩为原来的1.5倍
ArrayList():0、1、2、3、4、6、9...Integer.MAX_VALUE - 8
ArrayList(0):10、15、22、33、49...Integer.MAX_VALUE - 8
为什么最大容量为 Integer.MAX_VALUE - 8?
数组对象有一个额外的元数据,用于表示数组的大小(8bytes)
2、总结
都初始化为一个空的Object[],但对象不同,区别在扩容规则不一样
在JDK7中,ArrayList()实际上是调用了ArrayList(10),因为没有指定动态数组的初始容量,JDK会自动给动态数组初始化一个容量,以减少插入少量元素时动态数组的扩容开销
在JDK8中,基本差不多,只不过采用延迟初始化策略
相关文章推荐
- String/StringBuffer/StringBuilder的区别及源码分析
- Linux-0.11内核源码分析系列:关于线性地址,逻辑地址,物理地址的关系与区别
- 源码分析三(Vector与ArrayList的区别)
- SharePreferences源码分析(commit与apply的区别以及原理)
- Android 5.0源码分析---startService与bindService的区别
- Android开发之getMeasuredWidth和getWidth区别从源码分析
- ArrayList和LinkedList的区别,包括源码分析
- 源码分析Android bindService与startService区别
- 从源码上分析trigger和triggerHandle的区别
- [源码解析]HashMap和HashTable的区别(源码分析解读)
- JAVA面试题 从源码角度分析StringBuffer和StringBuilder的区别
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- String 方法中 replace 和 replaceAll 的区别详解(源码分析)
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- View的两种更新方法-从源码角度分析invalidate()和postInvalidate()的区别
- 关于 equals 和 == 的具体区别 从源码角度分析
- JVM源码分析之MetaspaceSize和MaxMetaspaceSize的区别
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- 唯快不破:结合内核实现源码分析 select poll epoll区别
- Android开发之getMeasuredWidth和getWidth区别从源码分析