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 ...
随机推荐
- 使用Kimi+Markmap总结网页内容生成思维导图
AI可以帮助我们更高效地阅读文章进行提炼总结,像上图这张思维导图,就是使用Kimi进行内容提炼,再使用markmap生成思维导图,下面讲解下详细实现步骤: 一.工具准备 Kimi,将文章或一篇网页投给 ...
- MySQL入门到实战详细教程
MySQL介绍 MySQL是一个开源的关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品,它广泛应用于各种Web应用程序和网站,MySQL使用结构化查 ...
- discuz论坛个人空间自定义css样式
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` discuz论坛个人空间自定义css样式 日期:2020- ...
- Flink状态(二)
Flink提供了不同的状态存储方式,并说明了状态如何存和存储在哪里. 状态可以被存储在Jvm的堆和堆外.根据状态存储方式的不同,Flink也能代替应用管理状态,意思是Flink能够进行内存管理(有必要 ...
- Linux中的inode
inode是什么 一个文件由两部分组成:元信息和数据. 在Linux中,inode包含文件的元信息,具体来说有以下内容: Size 文件的字节数 Uid 文件拥有者的User ID Gid 文件的Gr ...
- ISCSI配置与挂载
ISCSI介绍 iSCSI使用 TCP/IP 协议,来提供网络存储. 客户端挂载后,可以对其进行分区,进行格式化,就好像是安装在本机上的硬盘一样. 为了保证传输速率,通常采用光纤. 配置环境 Cent ...
- Linux查看系统占用
## 查看内存占用 #CPU占用最多的前10个进程: ps auxw|head -1;ps auxw|sort -rn -k3|head -10 #内存消耗最多的前10个进程 ps auxw|head ...
- Nginx配置以及热升级
目录 Nginx详解 1. Nginx关键特性 2. Nginx配置 2.1 event 2.2 http 2.2.1 log_format 2.2.2 sendfile 2.2.3 tcp_nopu ...
- 新版SpringBoot-Spring-Mybatis 数据库相关配置
application.properties server.port=8081 # ========================数据库相关配置===================== sprin ...
- 洛谷P5020
水一道绿题... #include<iostream> #include<utility> #include<algorithm> using namespace ...