为了照顾初学者,我分几分版本发出来

版本一:基础版本

实现对象创建、元素添加、重新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的更多相关文章

  1. 理解java容器底层原理--手动实现HashMap

    HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...

  2. 理解java容器底层原理--手动实现HashSet

    HashSet的底层其实就是HashMap,换句话说HashSet就是简化版的HashMap. 直接上代码: package com.xzlf.collection2; import java.uti ...

  3. 理解java容器底层原理--手动实现LinkedList

    Node java 中的 LIinkedList 的数据结构是链表,而链表中每一个元素是节点. 我们先定义一下节点: package com.xzlf.collection; public class ...

  4. (前篇:NIO系列 推荐阅读) Java NIO 底层原理

    出处: Java NIO 底层原理 目录 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步 ...

  5. Java面试底层原理

    面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心.以下是我个人总结,请参考: HashSet底层原理:(问了大几率 ...

  6. Java 容器 & 泛型:二、ArrayList 、LinkedList和Vector比较

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 继续上一篇的容器文章认识容器,泥瓦匠慢慢带你们走进List的容器解说.今天泥瓦匠想说说 ArrayLi ...

  7. 10分钟看懂, Java NIO 底层原理

    目录 写在前面 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步阻塞IO(Blocking ...

  8. Java 总结 数据底层原理 【包括 ArrayList、LinkedList、hash table、HashMap、Hashtable、ConcurrentHashMap、hash code、HashSet、LinkedHashMap、LinkedHashSet】

    1.ArrayList (1)底层是由动态数组实现的[使用了List接口]. (2)动态数组是长度不固定,随着数据的增多而变长. (3)如果不指定,默认长度为10,当添加的元素超过当前数组的长度时,会 ...

  9. Java 容器源码分析之 ArrayList

    概览 ArrayList是最常使用的集合类之一了.在JDK文档中对ArrayList的描述是:ArrayList是对list接口的一种基于可变数组的实现.ArrayList类的声明如下: 12 pub ...

随机推荐

  1. 非常诡异的IIS下由配置文件加上svg的mime头导致整个网站的静态文件访问报错误

    调试了两天遇到一个非常诡异的问题 一个系统稳定运行了很多年,是用mvc5+WIN2008R2  + .NET 4.5 +IIS环境下运行,非常稳定,最近想迁移到一台新的服务器,为了少麻烦在阿里云上买了 ...

  2. 字符串中的count()方法

    描述 Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. 语法 count()方法语法: str.count(sub, start= 0,e ...

  3. JavaScript实现图结构

    JavaScript实现图结构 一.图论 1.1.图的简介 什么是图? 图结构是一种与树结构有些相似的数据结构: 图论是数学的一个分支,并且,在数学中,树是图的一种: 图论以图为研究对象,研究顶点和边 ...

  4. Sql练习201908210951

    表结构: create table SalePlan ( PlanId ,) primary key, GoodsId int, PlanPrice decimal(,) ); go create t ...

  5. ANTLR随笔(一)

    学习背景 最近做项目需要开发一个类似Graphql的简单版的自定义查询功能. 功能主要是通过前端自定义的复查询条件来控制后端的查询字段以及最终返回的JSON格式. 最初准备直接使用Graphql实现但 ...

  6. MySQL 同步复制及高可用方案总结

    1.前言 mysql作为应用程序的数据存储服务,要实现mysql数据库的高可用.必然要使用的技术就是数据库的复制,如果主节点出现故障可以手动的切换应用到从节点,这点相信运维同学都是知道,并且可以实现的 ...

  7. win10配置易用命令行

    在 win10 下配置易用命令行 win10 相比 Linux 最大的短板之一是命令行. 这篇文章不会将 win10 配置到像Linux那样一行命令解决所有包的安装,只是从最大程度上方便开发. 我们主 ...

  8. springboot项目下的Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    今天遇到mybatis-puls的报错Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (n ...

  9. 1050 String Subtraction (20分)

    Given two strings S​1​​ and S​2​​, S=S​1​​−S​2​​ is defined to be the remaining string after taking ...

  10. Ubuntu 安装配置Dosbox

    1.安装dosbox sudo apt-get install dosbox 方法一: 2.挂载虚拟空间到dosbox的c盘 在linux终端输入dosbox,进入dosbox后输入 mount  c ...