在 Java 的 ArrayList 中,当数组的容量不足以存储新元素时,会触发扩容操作。ArrayList 的底层使用数组来存储元素,而扩容机制主要涉及到创建一个更大的数组,并将现有元素复制到新数组中。ArrayList 支持无参扩容和有参扩容两种机制。
无参扩容机制:
无参扩容是指首次的扩容大小是10,后面在元素数量达到容量上限时,ArrayList 会创建一个新的数组,其大小通常是原数组容量的1.5倍,并将原数组中的元素复制到新数组中。这个过程涉及到创建新数组、复制元素等步骤(copyOf方法)。
以下是无参扩容的源码示例:
//第一步
public boolean add (E e){
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//第二步
private void ensureCapacityInternal ( int minCapacity){ ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//第三步
private static int calculateCapacity (Object[]elementData,int minCapacity){
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}//DEFAULT_CAPACITY为10
return 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;
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);
}
有参扩容机制:
有参扩容是指允许开发者在添加元素时指定扩容的大小。通过传递一个整数作为参数,ArrayList 会根据指定的扩容大小进行数组的扩容。后面在元素数量达到容量上限时,ArrayList 会创建一个新的数组,其大小通常是原数组容量的1.5倍。
有参扩容的源码示例:
//第一步
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);
}
}
//第二步
private void ensureCapacityInternal ( int minCapacity){ ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//第三步
private static int calculateCapacity (Object[]elementData,int minCapacity){
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}//DEFAULT_CAPACITY为10
return 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;
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);
}
java.util.Vector 是 Java 中的一种动态数组实现,与 ArrayList 类似,它也支持无参扩容和有参扩容机制。Vector 是线程安全的,但在多线程环境下性能较差,已经不太推荐使用。
无参扩容机制:
无参扩容是指首次的扩容大小默认是10,后面在元素数量达到容量上限时,Vector 会创建一个新的数组,其大小通常是原数组容量的2倍,并将原数组中的元素复制到新数组中。这个过程涉及到创建新数组、复制元素等步骤(copyOf方法)。
以下是无参扩容的源码示例:
//第一步
public Vector() {
this(10);
}
//第二步
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//第三步
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
//第四步
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//第五步
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);
}
有参扩容机制:
有参扩容是指允许开发者在添加元素时指定扩容的大小。通过传递一个整数作为参数,Vector 会根据指定的扩容大小进行数组的扩容。后面在元素数量达到容量上限时,Vector 会创建一个新的数组,其大小通常是原数组容量的2倍。
有参扩容的源码示例:
//第一步
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//第二步
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
//第三步
protected AbstractList() {
}
//第四步
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
//第五步
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//第六步
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);
}
小结:ArrayList
和 Vector
都是 Java 集合框架中动态数组的实现,它们在很多方面非常相似,但也有一些关键的区别。在选择使用哪个类时,需要考虑到它们的性能、线程安全性和适用场景等因素。
ArrayList 和 Vector 的对比:
-
线程安全性:
-
ArrayList
:不是线程安全的,多个线程同时访问和修改ArrayList
可能会导致并发问题。 -
Vector
:是线程安全的,内部使用同步机制来确保多线程下的安全访问。
-
-
性能:
-
ArrayList
:由于不需要进行额外的同步操作,相对于Vector
在单线程环境下性能更好。 -
Vector
:由于需要进行同步操作,性能相对较差。在多线程环境下,由于同步开销,可能也比ArrayList
性能较差。
-
-
扩容机制:
-
ArrayList
和Vector
的扩容机制类似,但ArrayList
可以通过构造函数ArrayList(int initialCapacity)
或ensureCapacity(int minCapacity)
方法来设置初始容量,而Vector
只能通过构造函数来设置初始容量。
-
-
适用场景:
- 如果在单线程环境下使用,且不需要线程安全性,推荐使用
ArrayList
。 - 如果在多线程环境下使用,或者需要考虑线程安全性,可以考虑使用
Vector
。但请注意,现代 Java 中更倾向于使用并发集合(如ConcurrentHashMap
、CopyOnWriteArrayList
等)来实现更高效的线程安全。
- 如果在单线程环境下使用,且不需要线程安全性,推荐使用
如何选择:
-
性能要求:如果性能是首要考虑因素,且在单线程环境下使用,选择
ArrayList
。如果线程安全性更重要,可以考虑使用其他线程安全的集合,而不是Vector
。 -
线程安全性:如果需要在线程之间共享数据,或者在多线程环境下使用,而且没有更好的线程安全替代品,可以考虑使用
Vector
。但要知道Vector
的性能会受到影响。 -
现代替代品:在现代 Java 中,还有更适合多线程环境的集合实现,如
CopyOnWriteArrayList
或并发集合框架。这些集合能够提供更好的性能和线程安全性。文章来源:https://www.toymoban.com/news/detail-670120.html
综上所述,除非有特定的需求,现代 Java 中更倾向于使用其他集合实现,而不是直接使用 Vector
。在选择时,需要根据具体的需求和环境来权衡性能和线程安全性。文章来源地址https://www.toymoban.com/news/detail-670120.html
到了这里,关于Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!