Vector源码解读
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源码解读的更多相关文章
- jdk1.8.0_45源码解读——ArrayList的实现
jdk1.8.0_45源码解读——ArrayList的实现 一.ArrayList概述 ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素. ...
- Input源码解读——从"Show tabs"开始
Input源码解读--从"Show tabs"开始 本文基于Android T版本源码,梳理当用户在开发者选项中开启Show tabs功能后显示第点按操作的视觉反馈的原理,来进一步 ...
- SDWebImage源码解读之SDWebImageDownloaderOperation
第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...
- SDWebImage源码解读 之 NSData+ImageContentType
第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...
- SDWebImage源码解读 之 UIImage+GIF
第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...
- SDWebImage源码解读 之 SDWebImageCompat
第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
- SDWebImage源码解读之SDWebImageCache(下)
第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
随机推荐
- org.springframework.beans.BeanUtils属性赋值 Date类型处理转换为LocalDateTime, Date不能直接赋值给LocalDateTime
Date createTime = book.getCreateTime(); Date updateTime = book.getUpdateTime(); //属性值处理 BeanUtils.co ...
- 关于Compilation failed: internal java compiler error的解决方法(Idea)
关于Compilation failed: internal java compiler error的解决方法(Idea) idea编译项目时出现java: Compilation failed: i ...
- Java扫描文件目录大小及递归扫描
#Java扫描文件目录大小及递归扫描 package com.example.core.mydemo; import org.apache.commons.io.FileUtils; import j ...
- Thanos解码:打造企业级云原生监控解决方案
本文深入探讨了Thanos技术在云原生监控领域的应用,详细介绍了Thanos的基本概念.核心组件.安装配置步骤以及一个实战案例,帮助读者理解如何利用Thanos解决大规模监控数据的存储.查询和高可用性 ...
- 2024年软件架构趋势之AI与机器学习的关系
在当下这个信息爆炸的时代,我们经常会听到"AI"和"机器学习"这两个词.它们似乎总是携手出现,让人觉得它们就是一对不可分割的"好基友".但你 ...
- firewall-cmd设置NAT转换
配置ipv4转发 修改servera配置文件/etc/sysctl.conf ,修改参数为1 net.ipv4.ip_forward = 1 配置生效: sysctl -p 修改网卡的zone [ro ...
- 05-Python函数
函数定义与调用 函数由以下几个部分组成: 函数名 函数参数 函数体 返回值 定义一个函数: def showMyName(name): #定义函数 print(name) showMyName(&qu ...
- TensorFLow手写字识别深度学习网络分析详解
Tensorflow和MNIST简介 TensorFlow 是一个采用数据流图,用于数值计算的开源软件库.它是一个不严格的"神经网络"库,可以利用它提供的模块搭建大多数类型的神经网 ...
- 含税168元起!四核A53+NPU+PCIe+USB3.0,瑞芯微RK3562性价比真高!
- Codeforces Global Round 26 A~C2
惹啊啊啊啊,这场做得我发昏,最近总感觉不在状态,但还是再在冲击1600-1800的题目. A. Strange Splitting ---------------------------------题 ...