理解java容器底层原理--手动实现ArrayList
为了照顾初学者,我分几分版本发出来
版本一:基础版本
实现对象创建、元素添加、重新toString() 方法
package com.xzlf.collection;
/**
* 自定义一个ArrayList,体会底层实现原理
* 初始版本
* @author xzlf
*
* @param <E>
*/
public class MyArrayList<E> {
private Object[] elementDate;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList() {
elementDate = new Object[DEFAULT_CAPACITY];
}
public MyArrayList(int capacity) {
elementDate = new Object[capacity];
}
public void add(E element) {
elementDate[size++] = element;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(elementDate[i] + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<String>(20);
list.add("aa");
list.add("bb");
list.add("cc");
System.out.println(list);
}
}
测试运行
版本二:增加扩容
package com.xzlf.collection;
/**
* 自定义一个ArrayList,体会底层实现原理
* 增加扩容
* @author xzlf
*
* @param <E>
*/
public class MyArrayList2<E> {
private Object[] elementDate;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList2() {
elementDate = new Object[DEFAULT_CAPACITY];
}
public MyArrayList2(int capacity) {
elementDate = new Object[capacity];
}
public void add(E element) {
// 元素个数等于数组长度时 进行扩容操作
if(size == elementDate.length) {
Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
elementDate = newArray;
}
elementDate[size++] = element;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(elementDate[i] + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArrayList2<String> list = new MyArrayList2<String>();
for (int i = 0; i < 15; i++) {
list.add("aa" + i);
}
System.out.println(list);
}
}
测试:
版本三:添加get set方法以及数组边界检查
package com.xzlf.collection;
/**
* 增加get set 方法
* 增加数组边界检查
* @author xzlf
*
* @param <E>
*/
public class MyArrayList3<E> {
private Object[] elementDate;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList3() {
elementDate = new Object[DEFAULT_CAPACITY];
}
public MyArrayList3(int capacity) {
if(capacity < 0) {
throw new RuntimeException("数组容量不能为负数");
}else if(capacity == 0) {
elementDate = new Object[DEFAULT_CAPACITY];
}
elementDate = new Object[capacity];
}
public void add(E element) {
// 元素个数等于数组长度时 进行扩容操作
if(size == elementDate.length) {
Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
elementDate = newArray;
}
elementDate[size++] = element;
}
public E get(int index) {
checkRange(index);
return (E) elementDate[index];
}
public void set(E element, int index) {
checkRange(index);
elementDate[index] = element;
}
public void checkRange(int index) {
// 索引合法判断[0,size)
if(index < 0 || index > size -1) {
throw new RuntimeException("索引不合法:" + index);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(elementDate[i] + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArrayList3<String> list = new MyArrayList3<String>();
for (int i = 0; i < 15; i++) {
list.add("aa" + i);
}
System.out.println(list);
System.out.println(list.get(10));
list.set("bb", 10);
System.out.println(list.get(10));
System.out.println(list.get(-10));
}
}
测试:
版本四:增加remove、size、isEmpty
package com.xzlf.collection;
/**
* 增加remove()
* 增加size isEmpty
* @author xzlf
*
* @param <E>
*/
public class MyArrayList4<E> {
private Object[] elementDate;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList4() {
elementDate = new Object[DEFAULT_CAPACITY];
}
public MyArrayList4(int capacity) {
if(capacity < 0) {
throw new RuntimeException("数组容量不能为负数");
}else if(capacity == 0) {
elementDate = new Object[DEFAULT_CAPACITY];
}
elementDate = new Object[capacity];
}
public void add(E element) {
// 元素个数等于数组长度时 进行扩容操作
if(size == elementDate.length) {
Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
elementDate = newArray;
}
elementDate[size++] = element;
}
public E get(int index) {
checkRange(index);
return (E) elementDate[index];
}
public void set(E element, int index) {
checkRange(index);
elementDate[index] = element;
}
public void checkRange(int index) {
// 索引合法判断[0,size)
if(index < 0 || index > size -1) {
throw new RuntimeException("索引不合法:" + index);
}
}
public void remove(int index) {
int numMoved = size - index -1;
if(numMoved > 0) {
System.arraycopy(elementDate, index+1, elementDate, index, numMoved);
}
elementDate[--size] = null;
}
public void remove(E element) {
// 遍历所有元素,和传入的element比较,获取第一个为true的位置 删除
for (int i = 0; i < size; i++) {
if(element.equals(get(i))) {
remove(i);
}
}
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < size; i++) {
sb.append(elementDate[i] + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArrayList4<String> list = new MyArrayList4<String>();
for (int i = 0; i < 15; i++) {
list.add("aa" + i);
}
System.out.println(list);
list.remove("aa7");
System.out.println(list);
list.remove(3);
System.out.println(list);
System.out.println(list.size());
System.out.println(list.isEmpty());
}
}
测试:
理解java容器底层原理--手动实现ArrayList的更多相关文章
- 理解java容器底层原理--手动实现HashMap
HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...
- 理解java容器底层原理--手动实现HashSet
HashSet的底层其实就是HashMap,换句话说HashSet就是简化版的HashMap. 直接上代码: package com.xzlf.collection2; import java.uti ...
- 理解java容器底层原理--手动实现LinkedList
Node java 中的 LIinkedList 的数据结构是链表,而链表中每一个元素是节点. 我们先定义一下节点: package com.xzlf.collection; public class ...
- (前篇:NIO系列 推荐阅读) Java NIO 底层原理
出处: Java NIO 底层原理 目录 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步 ...
- Java面试底层原理
面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...
- Java 容器 & 泛型:二、ArrayList 、LinkedList和Vector比较
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 继续上一篇的容器文章认识容器,泥瓦匠慢慢带你们走进List的容器解说.今天泥瓦匠想说说 ArrayLi ...
- 10分钟看懂, Java NIO 底层原理
目录 写在前面 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步阻塞IO(Blocking ...
- Java 总结 数据底层原理 【包括 ArrayList、LinkedList、hash table、HashMap、Hashtable、ConcurrentHashMap、hash code、HashSet、LinkedHashMap、LinkedHashSet】
1.ArrayList (1)底层是由动态数组实现的[使用了List接口]. (2)动态数组是长度不固定,随着数据的增多而变长. (3)如果不指定,默认长度为10,当添加的元素超过当前数组的长度时,会 ...
- Java 容器源码分析之 ArrayList
概览 ArrayList是最常使用的集合类之一了.在JDK文档中对ArrayList的描述是:ArrayList是对list接口的一种基于可变数组的实现.ArrayList类的声明如下: 12 pub ...
随机推荐
- iOS 预渲染加速图像显示
使用 UITableView 时,发现滚动时的性能还不错,但来回滚动时,第一次显示的图像不如再次显示的图像流畅,出现前会有稍许的停顿感. 于是猜想显示过的图像肯定是被缓存起来了,查了下文档后发现果然如 ...
- 从谷歌 GFS 架构设计聊开去
伟人说:“人多力量大.” 尼古拉斯赵四说:“没有什么事,是一顿饭解决不了的!!!如果有,那就两顿.” 研发说:“需求太多,人手不够.” 专家说:“人手不够,那就协调资源,攒人头.” 释义:一人拾柴火不 ...
- es6声明一个类
js语言的传统方式是通过定义构造函数,生成心得对象.是一种基于原型的面向对象系统.在es6中增加了class类的概念,可以使用class关键字来声明一个类.之后用这个类来实例化对象. 构造函数示例 c ...
- Go 开发环境搭建和代码调试
写这篇笔记的目的,主要是分享我在Go学习中遇到的坑.让后面的学习者能否参考有用的经验. 其中有一些小技巧,对初学者来说,可能会大大节约填坑的时间. 比如如何设置vscode的Go调试器,Go的语法高亮 ...
- IIS 组成
HTTP.sys http.sys 侦听来自网络的 HTTP 请求,将它们传递到 IIS 并返回响应. 它是一种可以从命令行停止和启动的服务. "NET STOP HTT ...
- android注册验证码的使用
主要是创建了验证码的生成类. 通过此生成类,与imageview相互联系起来,实现验证码显示.并添加点击事件,实现验证码的切换. 实验的截图如下:(验证码可以点击切换) 具体的关于验证码的生成类如下: ...
- javascript入门 之 zTree(十四 增删查改)(二)
<!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - addNodes / editName / rem ...
- 如何利用 githob 上传自己的网站
如何搭建自己的网页是每个学前端伙伴不可缺少的一个过程,特意去看过很多如何搭建的教程,但都看不懂觉得很麻烦, 在慢慢的学习中接触到githob,发现了一个大宝藏(如果一个code都不认识githob 那 ...
- 使用Network Emulator Toolkit工具模拟网络丢包测试(上)
弱网络测试包括延时和丢包二种场景下应用的功能是否正常: 网络延时测试使用Fiddler工具控制上下行数据传输延时时间来模拟网络延时场景: 网络丢包测试使用Network Emulator Toolki ...
- AJ学IOS(36)UI之手势事件旋转_缩放_拖拽
AJ分享,必须精品 效果 完成一个图片的捏合缩放,拖拽,旋转动作. 设计思路 拖拽: 首先是最简单的拖拽 //拖拽 -(void)panTest { UIPanGestureRecognizer *p ...