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

版本一:基础版本

实现对象创建、元素添加、重新toString() 方法

  1. package com.xzlf.collection;
  2. /**
  3. * 自定义一个ArrayList,体会底层实现原理
  4. * 初始版本
  5. * @author xzlf
  6. *
  7. * @param <E>
  8. */
  9. public class MyArrayList<E> {
  10. private Object[] elementDate;
  11. private int size;
  12. private static final int DEFAULT_CAPACITY = 10;
  13. public MyArrayList() {
  14. elementDate = new Object[DEFAULT_CAPACITY];
  15. }
  16. public MyArrayList(int capacity) {
  17. elementDate = new Object[capacity];
  18. }
  19. public void add(E element) {
  20. elementDate[size++] = element;
  21. }
  22. @Override
  23. public String toString() {
  24. StringBuilder sb = new StringBuilder("[");
  25. for (int i = 0; i < size; i++) {
  26. sb.append(elementDate[i] + ",");
  27. }
  28. sb.setCharAt(sb.length() - 1, ']');
  29. return sb.toString();
  30. }
  31. public static void main(String[] args) {
  32. MyArrayList<String> list = new MyArrayList<String>(20);
  33. list.add("aa");
  34. list.add("bb");
  35. list.add("cc");
  36. System.out.println(list);
  37. }
  38. }

测试运行

版本二:增加扩容

  1. package com.xzlf.collection;
  2. /**
  3. * 自定义一个ArrayList,体会底层实现原理
  4. * 增加扩容
  5. * @author xzlf
  6. *
  7. * @param <E>
  8. */
  9. public class MyArrayList2<E> {
  10. private Object[] elementDate;
  11. private int size;
  12. private static final int DEFAULT_CAPACITY = 10;
  13. public MyArrayList2() {
  14. elementDate = new Object[DEFAULT_CAPACITY];
  15. }
  16. public MyArrayList2(int capacity) {
  17. elementDate = new Object[capacity];
  18. }
  19. public void add(E element) {
  20. // 元素个数等于数组长度时 进行扩容操作
  21. if(size == elementDate.length) {
  22. Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
  23. System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
  24. elementDate = newArray;
  25. }
  26. elementDate[size++] = element;
  27. }
  28. @Override
  29. public String toString() {
  30. StringBuilder sb = new StringBuilder("[");
  31. for (int i = 0; i < size; i++) {
  32. sb.append(elementDate[i] + ",");
  33. }
  34. sb.setCharAt(sb.length() - 1, ']');
  35. return sb.toString();
  36. }
  37. public static void main(String[] args) {
  38. MyArrayList2<String> list = new MyArrayList2<String>();
  39. for (int i = 0; i < 15; i++) {
  40. list.add("aa" + i);
  41. }
  42. System.out.println(list);
  43. }
  44. }

测试:

版本三:添加get set方法以及数组边界检查

  1. package com.xzlf.collection;
  2. /**
  3. * 增加get set 方法
  4. * 增加数组边界检查
  5. * @author xzlf
  6. *
  7. * @param <E>
  8. */
  9. public class MyArrayList3<E> {
  10. private Object[] elementDate;
  11. private int size;
  12. private static final int DEFAULT_CAPACITY = 10;
  13. public MyArrayList3() {
  14. elementDate = new Object[DEFAULT_CAPACITY];
  15. }
  16. public MyArrayList3(int capacity) {
  17. if(capacity < 0) {
  18. throw new RuntimeException("数组容量不能为负数");
  19. }else if(capacity == 0) {
  20. elementDate = new Object[DEFAULT_CAPACITY];
  21. }
  22. elementDate = new Object[capacity];
  23. }
  24. public void add(E element) {
  25. // 元素个数等于数组长度时 进行扩容操作
  26. if(size == elementDate.length) {
  27. Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
  28. System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
  29. elementDate = newArray;
  30. }
  31. elementDate[size++] = element;
  32. }
  33. public E get(int index) {
  34. checkRange(index);
  35. return (E) elementDate[index];
  36. }
  37. public void set(E element, int index) {
  38. checkRange(index);
  39. elementDate[index] = element;
  40. }
  41. public void checkRange(int index) {
  42. // 索引合法判断[0,size)
  43. if(index < 0 || index > size -1) {
  44. throw new RuntimeException("索引不合法:" + index);
  45. }
  46. }
  47. @Override
  48. public String toString() {
  49. StringBuilder sb = new StringBuilder("[");
  50. for (int i = 0; i < size; i++) {
  51. sb.append(elementDate[i] + ",");
  52. }
  53. sb.setCharAt(sb.length() - 1, ']');
  54. return sb.toString();
  55. }
  56. public static void main(String[] args) {
  57. MyArrayList3<String> list = new MyArrayList3<String>();
  58. for (int i = 0; i < 15; i++) {
  59. list.add("aa" + i);
  60. }
  61. System.out.println(list);
  62. System.out.println(list.get(10));
  63. list.set("bb", 10);
  64. System.out.println(list.get(10));
  65. System.out.println(list.get(-10));
  66. }
  67. }

测试:

版本四:增加remove、size、isEmpty

  1. package com.xzlf.collection;
  2. /**
  3. * 增加remove()
  4. * 增加size isEmpty
  5. * @author xzlf
  6. *
  7. * @param <E>
  8. */
  9. public class MyArrayList4<E> {
  10. private Object[] elementDate;
  11. private int size;
  12. private static final int DEFAULT_CAPACITY = 10;
  13. public MyArrayList4() {
  14. elementDate = new Object[DEFAULT_CAPACITY];
  15. }
  16. public MyArrayList4(int capacity) {
  17. if(capacity < 0) {
  18. throw new RuntimeException("数组容量不能为负数");
  19. }else if(capacity == 0) {
  20. elementDate = new Object[DEFAULT_CAPACITY];
  21. }
  22. elementDate = new Object[capacity];
  23. }
  24. public void add(E element) {
  25. // 元素个数等于数组长度时 进行扩容操作
  26. if(size == elementDate.length) {
  27. Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
  28. System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
  29. elementDate = newArray;
  30. }
  31. elementDate[size++] = element;
  32. }
  33. public E get(int index) {
  34. checkRange(index);
  35. return (E) elementDate[index];
  36. }
  37. public void set(E element, int index) {
  38. checkRange(index);
  39. elementDate[index] = element;
  40. }
  41. public void checkRange(int index) {
  42. // 索引合法判断[0,size)
  43. if(index < 0 || index > size -1) {
  44. throw new RuntimeException("索引不合法:" + index);
  45. }
  46. }
  47. public void remove(int index) {
  48. int numMoved = size - index -1;
  49. if(numMoved > 0) {
  50. System.arraycopy(elementDate, index+1, elementDate, index, numMoved);
  51. }
  52. elementDate[--size] = null;
  53. }
  54. public void remove(E element) {
  55. // 遍历所有元素,和传入的element比较,获取第一个为true的位置 删除
  56. for (int i = 0; i < size; i++) {
  57. if(element.equals(get(i))) {
  58. remove(i);
  59. }
  60. }
  61. }
  62. public int size() {
  63. return size;
  64. }
  65. public boolean isEmpty() {
  66. return size == 0;
  67. }
  68. @Override
  69. public String toString() {
  70. StringBuilder sb = new StringBuilder("[");
  71. for (int i = 0; i < size; i++) {
  72. sb.append(elementDate[i] + ",");
  73. }
  74. sb.setCharAt(sb.length() - 1, ']');
  75. return sb.toString();
  76. }
  77. public static void main(String[] args) {
  78. MyArrayList4<String> list = new MyArrayList4<String>();
  79. for (int i = 0; i < 15; i++) {
  80. list.add("aa" + i);
  81. }
  82. System.out.println(list);
  83. list.remove("aa7");
  84. System.out.println(list);
  85. list.remove(3);
  86. System.out.println(list);
  87. System.out.println(list.size());
  88. System.out.println(list.isEmpty());
  89. }
  90. }

测试:

理解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. 基于 Spring Cloud 的微服务架构实践指南(上)

    show me the code and talk to me,做的出来更要说的明白 GitHub 项目learnSpringCloud同步收录 我是布尔bl,你的支持是我分享的动力! 一. 引入 上 ...

  2. 调试 node.js 程序

    调试 node.js 程序 在程序开发中,如何快速的查找定位问题是一项非常重要的基本功.在实际开发过程中,或多或少都会遇到程序出现问题导致无法正常运行的情况,因此,调试代码就变成了一项无法避免的工作. ...

  3. 微信阻止ios下拉回弹,橡皮筋效果

    直接阻止touchmove事件就好了(需设置passive: false): document.addEventListener("touchmove", function(evt ...

  4. 【WPF学习】第六十四章 构建基本的用户控件

    创建一个简单用户控件是开始自定义控件的好方法.本章主要介绍创建一个基本的颜色拾取器.接下来分析如何将这个控件分解成功能更强大的基于模板的控件. 创建基本的颜色拾取器很容易.然而,创建自定义颜色拾取器仍 ...

  5. VUE CLI3.0安装及配置

    # 安装 npm install -g @vue/cli # 查看已安装版本vue --version 或者 vue -V # 卸载 npm uninstall @vue/cli -g # 新建项目 ...

  6. Hadoop(八):YARN框架简介

    YARN组件图 Container是YARN框架中对应资源的抽象,封装了运行节点上的资源(内存+CPU) NodeManager负责Container状态的维护,通过心跳,把资源信息(剩余CPU.内存 ...

  7. docker-compose中redis查询版本

    1.查询CONTAINER ID docker ps 2.进入容器,查询版本号信息 docker exec -it CONTAINER ID /bin/bash 3.查询到redis中的redis-s ...

  8. go中的面向对象总结

    我们总结一下前面看到的:Go 没有类,而是松耦合的类型.方法对接口的实现. OO 语言最重要的三个方面分别是:封装,继承和多态,在 Go 中它们是怎样表现的呢? 封装(数据隐藏):和别的 OO 语言有 ...

  9. 【网络编程01】socket的基础知识-简单网络通信程序

    1.什么是socket socket(套接字),简单来说是IP地址与端口(port)的组合,可以与远程主机的应用程序进行通信.通过IP地址可以确定一台主机,而通过端口则可以确定某一个应用程序.IP+端 ...

  10. 8.4 StringBuilder的介绍及用法(String 和StringBuilder区别)

    * StringBuilder:是一个可变的字符串.字符串缓冲区类.** String和StringBuilder的区别:* String的内容是固定的.(方法区的内容)* StringBuilder ...