Vector底层原理

简介: Vector底层原理

Vector源码分析

Vector于ArrayList类似同样是数组类型,但是是线程安全的,为什么线程安全?在增删改方法中都加上了synchronized关键字

成员变量

protected Object[] elementData;//存储ArrayList元素的临时数组
protected int elementCount;//存储元素的个数
protected int capacityIncrement;//扩容容量

构造函数

1.无参构造函数

默认初始容量10

public Vector() {
        this(10);
    }

2.有参构造函数

指定Vector的初始容量和扩容时的增长系数为0

public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

指定Vector的初始容量和扩容时的增长系数大小

public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

根据传入集合创建一个Vector数组

public Vector(Collection<? extends E> c) {
    Object[] a = c.toArray();
    elementCount = a.length;
    if (c.getClass() == ArrayList.class) {
        elementData = a;
    } else {
        elementData = Arrays.copyOf(a, elementCount, Object[].class);
    }
}

增加方法

addElement(E obj)

public synchronized void addElement(E obj) {
        modCount++;//修改数+1
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;//在数组中设置元素位置
    }

判断是否需要扩容

private void ensureCapacityHelper(int minCapacity) {
    //当前元素个数大于数组容量就扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

扩容方法

private void grow(int minCapacity) {
        int oldCapacity = elementData.length;//10
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);//0>0?0:10
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

以上代码表示,默认会创建一个10长度的数组,当第11个参数添加的时候,进入grow方法,oldCapacity=10,newCapacity=10+10=20,最后copy数组。因此Vector扩容容量为原来的两倍。

插入方法

insertElementAt(E obj, int index)方法

在指定位置插入

public synchronized void insertElementAt(E obj, int index) {
    modCount++;
    //判断下标索引是否合理
    if (index > elementCount) {
        throw new ArrayIndexOutOfBoundsException(index
                                                 + " > " + elementCount);
    }
    //判断是否需要扩容
    ensureCapacityHelper(elementCount + 1);
    //数组Copy 把当前位置留出来,index到后面的元素全部后移一个
    System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
    //插入当前元素
    elementData[index] = obj;
    //数量+1
    elementCount++;
}

删除方法

removeElementAt(int index)方法

删除指定索引位置的方法

public synchronized void removeElementAt(int index) {
    modCount++;
    //判断索引是否合理
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    else if (index < 0) {
        throw new ArrayIndexOutOfBoundsException(index);
    }
    //获取删除位置后面元素的个数
    int j = elementCount - index - 1;
    if (j > 0) {
        //把后面元素移动到当前位置来
        System.arraycopy(elementData, index + 1, elementData, index, j);
    }
    //数组容元素-1
    elementCount--;
    //最后多余的位置置为空
    elementData[elementCount] = null;
}

removeAllElements()

public synchronized void removeAllElements() {
    modCount++;//修改次数
    //遍历删除元素
    for (int i = 0; i < elementCount; i++)
        elementData[i] = null;//赋值为空
    elementCount = 0;//元素个数为0
}

其他方法

elementAt(int index)

根据索引获取元素

public synchronized E elementAt(int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }
    return elementData(index);
}

firstElement()

获取第一个元素

public synchronized E firstElement() {
    if (elementCount == 0) {
        throw new NoSuchElementException();
    }
    return elementData(0);
}

lastElement()

获取最后一个元素

public synchronized E lastElement() {
    if (elementCount == 0) {
        throw new NoSuchElementException();
    }
    return elementData(elementCount - 1);
}

setElementAt(E obj, int index)

根据索引位置设置元素

public synchronized void setElementAt(E obj, int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    elementData[index] = obj;
}

indexOf(Object o, int index)

在指定范围内查找元素索引

public synchronized int indexOf(Object o, int index) {
 //判断对象是否为空,返回-1
    if (o == null) {
        for (int i = index ; i < elementCount ; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = index ; i < elementCount ; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;//未匹配
}

lastIndexOf(Object o, int index)

在指定范围内倒序查找元素索引

public synchronized int lastIndexOf(Object o, int index) {
    if (index >= elementCount)
        throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
    if (o == null) {
        for (int i = index; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = index; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
相关文章
|
6月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
|
设计模式 监控 网络协议
socket通信处于网络协议那一层和两种接收发送消息方式
socket通信处于网络协议那一层和两种接收发送消息方式
317 2
|
12月前
|
算法 网络协议 数据挖掘
阿里云通用算力型U1实例性能、适用场景、与经济型e区别、收费标准参考
在阿里云目前的活动中,通用算力型u1实例是一款价格相对较低且性价比较高的实例规格,通用算力型Universal实例(U实例)能提供均衡的计算、内存和网络资源,支持多种处理器和多种处理器内存配比。该类型实例依托阿里云资源池化技术和智能调度算法进行动态资源管理,为您的应用提供持续的算力保障、稳定性保障、供应及弹性保障,可以满足大多数场景下的应用需求,是一款具有高性价比的企业级实例。本文为大家介绍通用算力型U1实例的性能、适用场景、收费标准,以及和经济型e实例的区别,以供参考。
|
消息中间件 存储 监控
RocketMQ消息重试机制解析!
RocketMQ消息重试机制解析!
920 1
RocketMQ消息重试机制解析!
|
安全 算法 网络安全
【第五章】软件设计师 之 系统安全分析与设计
软件设计师 之 系统安全分析与设计备考资料
【第五章】软件设计师 之 系统安全分析与设计
|
Java 应用服务中间件 nginx
【Azure Spring Apps】Spring App部署上云遇见 502 Bad Gateway nginx
在部署Azure Spring App后,用户遇到502 Bad Gateway错误,问题源于Nginx。解决方案是检查并关闭Spring App的ingress-to-app TLS配置,因为若未启用HTTPS访问,Nginx通过HTTPS访问应用会导致此错误。
226 2
|
芯片 数据格式 索引
|
Web App开发 资源调度 Apache
|
前端开发 定位技术 API
百度地图API:根据起始点经纬度坐标确认最佳路线规划
百度地图API:根据起始点经纬度坐标确认最佳路线规划
236 0
|
弹性计算 网络安全
ECS由于/usr/lib/systemd/system/sshd.service配置错误导致ssh无法启动
ECS由于/usr/lib/systemd/system/sshd.service配置错误导致ssh无法启动