Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码

这篇具有很好参考价值的文章主要介绍了Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

小结:
ArrayListVector 都是 Java 集合框架中动态数组的实现,它们在很多方面非常相似,但也有一些关键的区别。在选择使用哪个类时,需要考虑到它们的性能、线程安全性和适用场景等因素。

ArrayList 和 Vector 的对比:

  1. 线程安全性

    • ArrayList:不是线程安全的,多个线程同时访问和修改 ArrayList 可能会导致并发问题。
    • Vector:是线程安全的,内部使用同步机制来确保多线程下的安全访问。
  2. 性能

    • ArrayList:由于不需要进行额外的同步操作,相对于 Vector 在单线程环境下性能更好。
    • Vector:由于需要进行同步操作,性能相对较差。在多线程环境下,由于同步开销,可能也比 ArrayList 性能较差。
  3. 扩容机制

    • ArrayListVector 的扩容机制类似,但 ArrayList 可以通过构造函数 ArrayList(int initialCapacity)ensureCapacity(int minCapacity) 方法来设置初始容量,而 Vector 只能通过构造函数来设置初始容量。
  4. 适用场景

    • 如果在单线程环境下使用,且不需要线程安全性,推荐使用 ArrayList
    • 如果在多线程环境下使用,或者需要考虑线程安全性,可以考虑使用 Vector。但请注意,现代 Java 中更倾向于使用并发集合(如 ConcurrentHashMapCopyOnWriteArrayList 等)来实现更高效的线程安全。

如何选择:

  1. 性能要求:如果性能是首要考虑因素,且在单线程环境下使用,选择 ArrayList。如果线程安全性更重要,可以考虑使用其他线程安全的集合,而不是 Vector

  2. 线程安全性:如果需要在线程之间共享数据,或者在多线程环境下使用,而且没有更好的线程安全替代品,可以考虑使用 Vector。但要知道 Vector 的性能会受到影响。

  3. 现代替代品:在现代 Java 中,还有更适合多线程环境的集合实现,如 CopyOnWriteArrayList 或并发集合框架。这些集合能够提供更好的性能和线程安全性。

综上所述,除非有特定的需求,现代 Java 中更倾向于使用其他集合实现,而不是直接使用 Vector。在选择时,需要根据具体的需求和环境来权衡性能和线程安全性。文章来源地址https://www.toymoban.com/news/detail-670120.html

到了这里,关于Java中ArrayList的底层扩容机制和Vector的底层扩容机制,以及ArrayList和Vector的对比与选择。附源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 源码分析——ArrayList源码+扩容机制分析

    ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayList 继承于 AbstractList ,实现了 List , RandomAccess , Cloneable , ja

    2024年02月14日
    浏览(46)
  • vector扩容机制

    在学习了vector的时候,总说linux下是以二倍扩容的,VS是以1.5倍扩容的。 但是想一想为什么扩容是这样的呢,为什么不能是3倍或者其他倍数呢?  所以带着这些疑问,接着往下看。 首先,我们要知道vector的扩容机制:当向vector插入元素的时候,即当_finish == _end_of_storage,可能

    2024年01月15日
    浏览(49)
  • c++ vector的扩容机制

    1、当向vector push_back一个元素时,如果此时元素个数超过了vector的容量,会触发扩容 2、扩容的过程是:开辟新空间-拷贝旧空间的元素-释放旧空间 3、扩容过程中开辟新空间的大小影响着往vector插入元素的效率: 如果新空间大小为旧空间大小+1,也就是边插入边扩容,这样每

    2024年02月10日
    浏览(38)
  • C++中STL的vector扩容机制

    前阵子面试的时候,被问到往vector中插入一个数据可能会发生什么? 我答:可能会 扩容 ; 为啥vector支持变长? 我答:它实在堆上动态申请内存,因此有自己的一套扩容机制,可以操作内存大小; 它有size()和capacity()记录当前的有效元素个数和容量, 还有配套的resize()管理实际存放

    2024年02月20日
    浏览(31)
  • java面试基础 -- ArrayList 和 LinkedList有什么区别, ArrayList和Vector呢?

    目录 基本介绍 有什么不同?? ArrayList的扩容机制 ArrayLIst的基本使用 ArrayList和Vector 还记得我们的java集合框架吗, 我们来复习一下, 如图:          可以看出来 ArrayList和LinkedList 都是具体类, 他们都是接口List的实现类. 但是他们底层的逻辑是不同的, 相信学过这个的应该大概有个

    2024年02月12日
    浏览(39)
  • java 数据结构 ArrayList源码底层 LinkedList 底层源码 迭代器底层

    对于数据结构我这边只告诉你右边框框里的 栈的特点:后进先出,先进后出,入栈也成为压栈,出栈也成为弹栈 栈就像一个弹夹 队列先进先出后进后出 队列像排队 链表查询满 但是增删快(相对于数组而言) 拓展:还有一个双向链表 他在查询元素的时候更快些,因为他在拿到一个元素

    2024年02月05日
    浏览(48)
  • Java实现ArrayList和底层源码讲解

    🎉🎉🎉 点进来你就是我的人了 博主主页: 🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔 🦾🦾🦾 目录 一. 模拟实现ArrayList​编辑 1.定义顺序顺序表 2. 函数实现 (1) 打印顺序表display()函数 (2) 新增元素函数add() (默认在数组最后新增) (3) 在 pos 位置新增元

    2023年04月16日
    浏览(39)
  • [C++历练之路]vector的介绍以及底层模拟实现

    W...Y的主页 😊 代码仓库分享 💕 🍔前言: 我们学习了STL中的string以及其所有重要接口并进行了模拟实现,但是STL中包含的内容不止于此。学习了string之后继续学习STL中的vector,学习成本会大大降低,因为他们非现类似,现在就让我们进入vector的世界中吧! 目录 vector的介绍

    2024年02月04日
    浏览(46)
  • 【JAVA语言-第15话】集合框架(二)——List、ArrayList、LinkedList、Vector集合

    目录 List集合 1.1 概述 1.2 特点 1.3 常用方法 1.4 ArrayList集合 1.4.1 概述  1.4.2 练习 1.5 LinkedList集合  1.5.1 概述 1.5.2 特点 1.5.3 常用方法 1.5.4 练习 1.6 Vector类 1.6.1 概述 1.6.2 练习 1.7 List实现类的异同点         java.util.List: List是一个接口,它继承自Collection接口。 常用的实现

    2024年01月25日
    浏览(57)
  • HashMap的扩容机制、初始化容量大小的选择、容量为什么是2的次幂

    先来看看HashMap中的成员属性 解释: size 当前的容器中Entry的数量,也就是当前K-V的数量 loadFactory 装载因子,用来衡量HashMap满的程度, loadFactory的默认值是0.75 threshold 临界值, 当实际KV数量超过threshold时,就会触发扩容机制 。 threshold = capatity * loadFactory 容量capatity 除了以上这

    2023年04月26日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包