理解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 ...
随机推荐
- 最小生成树(次小生成树)(最小生成树不唯一) 模板:Kruskal算法和 Prim算法
Kruskal模板:按照边权排序,开始从最小边生成树 #include<algorithm> #include<stdio.h> #include<string.h> ...
- django中 对Mysql数据库的建表
Django操作Mysql数据库: 1.1 在settings中,配置数据库相关参数,所以无需修改,这里我们看一下: DATABASES = { 'default': { # 这里可以指定使用的数据库 ...
- [noip模拟]祖孙询问<LCA>
[问题描述] 已知一棵n个节点的有根树.有m个询问.每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系. [输入格式] 输入第一行包括一个整数n表示节点个数. 接下来n行每行一对整数对a和b表示 ...
- STM32CubeMX的安装
1.下载STM32CubeMX 在ST的官方网站上下载STM32CubeMXXX软件的安装包. 下载的安装包如下图所示.双击SetupSTM32CubeMX-5.0.1.exe. 安装STM32Cub ...
- 1053 Path of Equal Weight (30分)(并查集)
Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weig ...
- 1006 Sign In and Sign Out (25 分)
At the beginning of every day, the first person who signs in the computer room will unlock the door, ...
- 剑指offer—单链表反转的三种实现方法
单链表的反转可以用递归.非递归和栈的方法实现 链表节点定义: struct ListNode{ int val; Node* next; ListNode(int x):val(x),next(nul ...
- MyBatis(七):使用注解替代xml文件
本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...
- PowerShell入门简介
文章更新于:2020-03-03 一.PowerShell简介 说实话,我总感觉 PowerShell 是 cmd 的加强版,但是看官方介绍,功能甚是强大,用处有待我们发掘. 二.PowerShell ...
- (js描述的)数据结构[树结构之红黑树](13)
1.二叉送搜索树的缺点: 2.红黑树难度: 3.红黑树五大规则: 4.红黑树五大规则的作用: 5.红黑树二大变换: 1)变色 2)旋转 6.红黑树的插入五种变换情况: 先声明--------插入的数据 ...