1.背景

阅读源码是提高编程技能的有效方式...

面试中也经常问到源码相关的问题.....

2.源码解读

在解读Vector时大家可以先解读ArrayList,因为这个两个的逻辑几乎是一样的....

ArrayList源码解读:https://www.cnblogs.com/newAndHui/p/16101626.html

区别在于

1.Vector的很多方法都是同步的即线程安全的,二ArrayList的很多方法时线程非同步的;

2.Vector扩容默认是原来的1倍,二ArrayList默认是按照原来的1.5倍扩容;

3.Vectory对象创建时默认数组长度为10,而ArrayList对象创建时是一个空数组,在添加第一个元素是才设置数组长度为10

阅读源码前自己写一个与Vector功能差不多的对象MyVector,相信你看懂了MyVector,那么Vector你就自然懂了...

package com.ldp.collection.my;

import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.RandomAccess; /**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 04/05 10:51
* @description
*/
public class MyVector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = -2767605614048989439L;
protected Object[] elementData; // 存放元素的数组对象
protected int elementCount; // 存放的元素个数
protected int capacityIncrement; // 数组扩容时的扩容量,默认为0,表示安装原来的1倍扩容,10扩容一次后为20
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 数组的最大容量 /**
* 无参数构造方法,默认容量为10
*/
public MyVector() {
this(10);
} /**
* 自定义容量的构造方法
*/
public MyVector(int initialCapacity) {
this(initialCapacity, 0);
} /**
* 自定义容量 和 扩容数的构造方法
*
* @param initialCapacity 数组长度
* @param capacityIncrement 扩容时的增加长度,默认为0,安装原来的1倍扩容
*/
public MyVector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " +
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
} /**
* 线程安全的,所以很多操作方法都是加了 synchronized 关键字的
*/
@Override
public synchronized boolean add(E e) {
// 累加修改次数
modCount++;
// 确定容量
ensureCapacityHelper(elementCount + 1);
// 在原来的元素后面加一个元素
elementData[elementCount++] = e;
return true;
} private void ensureCapacityHelper(int minCapacity) {
// 当最小需要的容量大于数组长度时进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
} private void grow(int minCapacity) {
// 原来的容量
int oldCapacity = elementData.length;
// 新的容量,capacityIncrement=0时,newCapacity=oldCapacity+oldCapacity,即按照原来的1倍扩容
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
// 加一倍后长度还是不够,则用传递过来的数值minCapacity(addAll来说,就是原长度+新集合长度)
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 超出最大值时计算
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 执行扩容
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;
} @Override
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index); return elementData(index);
} @SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
} @Override
public synchronized int size() {
return elementCount;
}
}

完美!

Vector源码解读的更多相关文章

  1. jdk1.8.0_45源码解读——ArrayList的实现

    jdk1.8.0_45源码解读——ArrayList的实现 一.ArrayList概述 ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素. ...

  2. Input源码解读——从"Show tabs"开始

    Input源码解读--从"Show tabs"开始 本文基于Android T版本源码,梳理当用户在开发者选项中开启Show tabs功能后显示第点按操作的视觉反馈的原理,来进一步 ...

  3. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  4. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  5. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  6. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  7. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  8. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  9. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

  10. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

随机推荐

  1. MAPJOIN中无法使用UDF

    今天在写SQL时,遇到了一个异常,提示semantic exception generate map join error unable to find class,udf编写的没毛病,其他SQL也有 ...

  2. C#.NET与JAVA互通之MD5哈希V2024

    C#.NET与JAVA互通之MD5哈希V2024 配套视频: 要点: 1.计算MD5时,SDK自带的计算哈希(ComputeHash)方法,输入输出参数都是byte数组.就涉及到字符串转byte数组转 ...

  3. ObjectMapper Json字符串的转换处理

    package com.example.demo; import com.example.pojo.User; import com.fasterxml.jackson.annotation.Json ...

  4. 用pm2命令管理你的node项目

    文章目录 前言 安装 运行项目 pm2的命令 前言 我在服务器上运行node项目,使用命令nohup npm start &,结果关闭终端之后,进程就会停止,看来nohup也不是万能的后台运行 ...

  5. 记录EF 排序配上自定义的比较器

    记录EF 排序配上自定义的比较器 前言 要求页面文件显示的时候能够按照序号去排序要求如下: 数据库有一个列存放文件名,如: 1.1文件 1.2文件 1.1.1文件 1.1.11文件1.0.txt 1. ...

  6. EF Core并发控制

    EF Core并发控制 并发控制概念 并发控制:避免多个用户同时操作资源造成的并发冲突问题. 最好的解决方案:非数据库解决方案 数据库层面的两种策略:悲观.乐观 悲观锁 悲观并发控制一般采用行锁 ,表 ...

  7. Linux内核:regmap机制

    背景 在学习SPI框架的时候,看到了有一个rtc驱动用到了regmap,本想通过传统方式访问spi接口的我,突然有点不适应,翻了整个驱动,愣是没有找到读写spi的范式:因此了解了regmap以后,才发 ...

  8. Linux进程退出:SIGINT、SIGTERM 和 SIGKILL 有关信号 区别

    背景 学习 海思SDK,查看例程的时候发现了类似下面的代码: int main(int argc, char *argv[]) { if(argc != 2) { printf("Usage ...

  9. docker部署微服务之注册中心

    1.首先要对对应服务的pom.xml文件进行修改,添加如下配置. 2.在微服务的pom.xml目录下建立Dockerfile文件 3.在Dockerfile当前目录下执行mvn clean insta ...

  10. 配置hive环境步骤(zookeeper高可用集群已搭建)

    安装mysql:1. 检查当前环境是否安装mysql服务(命令:rpm -qa | grep -i mysql)2. 卸载自带的mysql3. 卸载软件:rpm -e --nodeps mysql-l ...