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

版本一:基础版本

实现对象创建、元素添加、重新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. (连续的矩形)HDU - 1506

    题意:7 2 1 4 5 1 3 3  直接讲数据 :给出7个矩形的高,底长都为1,求最大的连通的矩形块的面积 思路:如果暴力的话肯定超时,有一个特别巧妙的预处理,如果我们知道每一个矩形的左右两边能延 ...

  2. 将java中Map对象转为有相同属性的类对象(json作为中间转换)

    java中Map对象转为有相同属性的类对象(json作为中间转换) 准备好json转换工具类 public class JsonUtil { private static ObjectMapper o ...

  3. SuperMap许可常见问题及解决办法

    一.试用许可申请可以直接在北京超图软件股份有限公司官网的“SuperMap 技术资源中心”申请试用许可,申请后您将获得:1.如果申请的是 SuperMap GIS 7C 系列产品的许可,您将获得 一个 ...

  4. Jedis连接外部Redis

    Jedis连接外部Redis 1.在服务器开放端口redis默认6379,如果有宝塔面板则还需要在宝塔放行6379端口 2.修改redis.conf 注释掉 绑定IP 127.0.0.1 # bind ...

  5. 商品spu 和 sku的关系

    总结一下在目前的电商系统中的商品涉及的属性spu,sku.搞清楚两者之间的关系对表的设计非常重要 spu Standard Product Unit (标准产品单位) ,一组具有共同属性的商品集 SK ...

  6. Python学习前端之JavaScript

    JavaScript介绍 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中),后将其改名ScriptEase(客户端执行的语言). Nets ...

  7. @RequestBody和@RequestParam的使用详解

    此次分享转载至:https://blog.csdn.net/justry_deng/article/details/80972817 这边文章讲解的比较透彻,主要是在springboot项目中进行使用 ...

  8. 简单记录下springboot+jms+activemq

    1. 安装ActiveMQ 到Apache官方网站下载最新的ActiveMQ的安装包,并解压到本地目录下后运行 2. pom.xml引入  springboot配置文件中填写相关配置 3.创建生产者 ...

  9. CentOS 7 Docker安装

    1. uname -a 查询机器信息,确保CPU为64位,且Linux内核在3.10版本以上 2. 更新yum包: yum update 3. 在 /etc/yum.repos.d下创建 docker ...

  10. 微信小程序--分享功能

    微信小程序--分享功能 微信小程序前段时间开放了小程序右上角的分享功能, 可以分享任意一个页面到好友或者群聊, 但是不能分享到朋友圈 这里有微信开发文档链接:点击跳转到微信分享功能API 入口方法: ...