如何手写一个ArrayList
写完HashMap,觉得手痒痒,所以隔了一天再来实现一下简单的ArrayList,ArrayList相比而言就非常的简单,主要的核心点有以下几个方面:
1.ArrayList的底层是由数组构成的
2.添加时需要考虑扩容问题
3.对于index索引的操作,需要考虑到下标不合法的异常
4.remove操作的时候,需要一点数学知识进行一下逻辑操作
下面贴出我的代码:
MyList接口:
public interface MyList {
// 求容量
int size();
// 是否为空
boolean isEmpty();
// 判断是否存在
boolean contains(Object o);
// 清空集合
void clear();
// 返回添加是否成功
boolean add(Object object);
// 返回删除是否成功
boolean remove(int index);
// 获取索引位置的值
Object get(int index);
}
MyArrayList 实现类的代码:
/***
* author kxm
* email 806857264@qq.com
* date 2018/9/17
*/
public class MyArrayList implements MyList {
private int size;
private Object[] elementData;
// JDK源码规定长度
private static final int DEFAULT_CAPACITY = 10;
// 构造方法 --- 空参
public MyArrayList(){
this(DEFAULT_CAPACITY);
}
// 有参构造方法
public MyArrayList(int initialCapacity){
/*
* 1.含参构造器
* 2.要对传入的初始量的合法性进行检测
* 3.通过新建数组实现
*/
if(initialCapacity < 0){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
elementData=new Object[initialCapacity];
}
// 返回长度
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
// 返回长度是否为0即可
return size == 0;
}
// 暂时只考虑直接equals的情况
@Override
public boolean contains(Object o) {
for(Object old : elementData){
if(o.equals(old)){
return true;
}
}
return false;
}
// 清除数组
@Override
public void clear() {
elementData = new Object[DEFAULT_CAPACITY];
size = 0;
}
@Override
public boolean add(Object object) {
ensureCapacity();
elementData[size] = object;
size++;
return true;
}
@Override
public boolean remove(int index) {
/*
* 1.下标合法性检测
* 2.删除指定下标对象,并返回其值
* 3.通过数组复制实现
* 4.因为前移,数组最后一位要置为空
*/
rangeCheck(index);
int arrnums=size - index - 1;
if(arrnums > 0){
// 思路:从被删除的索引的下一位开始复制给新的当前数组索引的起始位置,长度为size - index - 1 --- 数学问题
System.arraycopy(elementData, index+1, elementData,index, arrnums);
}
elementData[--size]=null;
return true;
}
@Override
public Object get(int index) {
rangeCheck(index);
return elementData[index];
}
// 数组容量检测方法 --- 如果超了就得扩容
private void ensureCapacity(){
if(size==elementData.length){
Object[] newArray=new Object[size * 2 + 1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData=newArray;
}
}
// 对索引下标进行合法性检查
private void rangeCheck(int index){
if(index<0||index>=size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return "MyArrayList{" +
"elementData=" + Arrays.toString(elementData) +
'}';
}
}
如何手写一个ArrayList的更多相关文章
- 手写一个简单的ElasticSearch SQL转换器(一)
一.前言 之前有个需求,是使ElasticSearch支持使用SQL进行简单查询,较新版本的ES已经支持该特性(不过貌似还是实验性质的?) ,而且git上也有elasticsearch-sql 插件, ...
- 浅析MyBatis(二):手写一个自己的MyBatis简单框架
在上一篇文章中,我们由一个快速案例剖析了 MyBatis 的整体架构与整体运行流程,在本篇文章中笔者会根据 MyBatis 的运行流程手写一个自定义 MyBatis 简单框架,在实践中加深对 MyBa ...
- 手写一个LRU工具类
LRU概述 LRU算法,即最近最少使用算法.其使用场景非常广泛,像我们日常用的手机的后台应用展示,软件的复制粘贴板等. 本文将基于算法思想手写一个具有LRU算法功能的Java工具类. 结构设计 在插入 ...
- 『练手』手写一个独立Json算法 JsonHelper
背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- 【spring】-- 手写一个最简单的IOC框架
1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...
- 放弃antd table,基于React手写一个虚拟滚动的表格
缘起 标题有点夸张,并不是完全放弃antd-table,毕竟在react的生态圈里,对国人来说,比较好用的PC端组件库,也就antd了.即便经历了2018年圣诞彩蛋事件,antd的使用者也不仅不减,反 ...
- 手写实现ArrayList & LinkedList
微信公众号:程序媛的非程序人生 关注可了解更多资讯.问题或建议,请公众号留言; 1.手写实现ArrayList 2.手写实现 LinkedList 3.LinkedList的数据结 ...
- 只会用就out了,手写一个符合规范的Promise
Promise是什么 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Prom ...
随机推荐
- 附016.Kubernetes_v1.17.4高可用部署
一 kubeadm介绍 1.1 概述 参考<附003.Kubeadm部署Kubernetes>. 1.2 kubeadm功能 参考<附003.Kubeadm部署Kubernetes& ...
- 2.K8S的核心资源管理方法
目录 1.1陈述式资源管理方法 1.1.1.管理名称空间资源 1.1.2.管理Deployment资源 1.1.3.管理Service资源 1.1.4.kubectl用法总结 1.2.声明式资源管理方 ...
- Java多线程与并发基础
CS-LogN思维导图:记录专业基础 面试题 开源地址:https://github.com/FISHers6/CS-LogN 多线程与并发基础 实现多线程 面试题1:有几种实现线程的方法,分别是什么 ...
- 总结下c/c++的一些调试经验
工作2年,干了一年ARM平台嵌入式,一年后台,总结下这两年开发中调试的经验.我把调试手段分成2种:打印日志和用工具分析.因为平时主要开发在Linux平台,就以GDB为例 一.打印日志 1. 合理设置日 ...
- Scrapy学习1:安装
Install Scrapy 熟悉PyPI的话,直接一句 pip install Scrapy 但是有时候需要处理安装依赖,不能直接一句命令就安装结束,这个和系统有关. 我用的Ubuntu,这里仅介绍 ...
- Linux文件目录和访问权限
前言 本文知识点是曾经学习过程中收录整理的,方便学习使用,并非在下撰写. 一>Lniux目录结构 /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录.所有的东西都是从这里开始. ...
- @PathVariable @RequestParam@RequestBody
@PathVariable 当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariabl ...
- redis基础二----操作hash
上面usr就是hash的名字,usr这个hash中存储了key 为id.name和age的值 一个hash相当于一个数据对象,里面可以存储key为id name age的值 2.批量插入一个hash数 ...
- MySQL按指定字符合并及拆分
按照指定字符进行合并或拆分是经常碰到的场景,MySQL在合并的写法上比较简单,但是按指定字符拆分相对比较麻烦一点(也就是要多写一些字符).本文将举例演示如何进行按照指定字符合并及拆分. 1. 合并 M ...
- Spring IoC 循环依赖的处理
前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 本篇文章主要介绍 Spring IoC 是 ...