JAVA面试题 手写ArrayList的实现,在笔试中过关斩将?
面试官Q1:可以手写一个ArrayList的简单实现吗?
我们都知道ArrayList是基于数组实现,如果让你实现JDK源码ArrayList中add()、remove()、get()方法,你知道如何实现吗?这一节,我们不看源码,我们想想如何简单的实现ArrayList几个基本方法?
确定数据结构
我们知道,ArrayList中无论什么数据都能放,是不是意味着它是一个Object类型,既然是数组,那么是不是Object[]数组类型的?所以我们定义的数据结构如下:
private Object[] elementData;
private int size;
设置自定义的MyArrayList的长度为10
public MyArrayList(){
this(10);
}
public MyArrayList(int initialCapacity){
if(initialCapacity<0){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
elementData = new Object[initialCapacity];
}
有了存放数据的位置,接下来,我们想想如何将数据放入数组?
添加数据
public void add(Object obj){
elementData[size++]=obj;
}
每添加一个元素,size就会自增1,我们定义的数组长度为10,当我们添加到11个元素的时候,显然没有地方存放新添加的数据,这个时候我们需要对数组进行扩容处理对上面代码做如下修改:
public void add(Object obj){
if(size==elementData.length){
//创建一个新的数组,并且这个数组的长度是原数组长度的2倍
Object[] newArray = new Object[size*2];
//使用底层拷贝,将原数组的内容拷贝到新数组
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
//并将新数组赋值给原数组的引用
elementData = newArray;
}
//新来的元素,直接赋值
elementData[size++]=obj;
}
用一张图来表示就是这样的:
查询数据
public Object get(int index){
return elementData[index];
}
删除数据
接着我们看一下删除的操作。ArrayList支持两种删除方式:
按照下标删除
按照元素删除,这会删除ArrayList中与指定要删除的元素匹配的第一个元素
对于ArrayList来说,这两种删除的方法差不多,都是调用的下面一段代码:
public void remove(int index){
//删除指定位置的对象
//a b d e
int numMoved = size - index - 1;
if (numMoved > 0){
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
}
elementData[--size] = null; // Let gc do its work
}
其实做的事情就是两件:
把指定元素后面位置的所有元素,利用System.arraycopy方法整体向前移动一个位置
最后一个位置的元素指定为null,这样让gc可以去回收它
用图表示是这样的:

指定位置添加数据
把从指定位置开始的所有元素利用System,arraycopy方法做一个整体的复制,向后移动一个位置(当然先要用ensureCapacity方法进行判断,加了一个元素之后数组会不会不够大),然后指定位置的元素设置为需要插入的元素,完成了一次插入的操作。
public void add(int index,Object obj){
ensureCapacity(); //数组扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = obj;
size++;
}
用图表示这个过程是这样的:
总结一下
从上面的几个过程总结一下ArrayList的特点:
ArrayList底层以数组实现,是一种随机访问模式,通过下标索引定位数据,所以查找非常快
ArrayList在顺序添加一个元素的时候非常方便,只是往数组里面添加了一个元素而已(这里指的末尾添加数据)
当删除元素的时候,涉及到一次元素复制移位,如果要复制的元素很多,那么就会比较耗费性能
当插入元素的时候,涉及到一次元素复制移位,如果要复制的元素很多,那么就会比较耗费性能
因此,ArrayList比较适合顺序添加、随机访问的场景。
JAVA面试题 手写ArrayList的实现,在笔试中过关斩将?的更多相关文章
- 面试必会之ArrayList源码分析&手写ArrayList
简介 ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高. 线程 ...
- 三 基于Java动态数组手写队列
手写队列: package dataStucture2.stackandqueue; import com.lt.datastructure.MaxHeap.Queue; import dataStu ...
- 二 基于java动态数组手写栈
package dataStucture2.stack; import dataStucture2.array.MyDynamicArray; /** * 基于动态数组手写栈 * 设计时,栈中仅栈顶对 ...
- java面试:手写代码
二分查找法. /** * 二分查找法:给定一组有序的数组,每次都从一半中查找.直到找到要求的数据. * 主要是得找到下标的表示方法. */ public class BinaryFind { /** ...
- Java 面试题 自己写的答案
基本概念 操作系统中 heap 和 stack 的区别 栈(stack)与堆(heap)都是Java用来在内存中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 在函 ...
- java面试之手写单例模式
为什么要有单例模式 实际编程应用场景中,有一些对象其实我们只需要一个,比如线程池对象.缓存.系统全局配置对象等.这样可以就保证一个在全局使用的类不被频繁地创建与销毁,节省系统资源. 实现单例模式的几个 ...
- Android 手写Binder 教你理解android中的进程间通信
关于Binder,我就不解释的太多了,网上一搜资料一堆,但是估计还是很多人理解的有困难.今天就教你如何从 app层面来理解好Binder. 其实就从我们普通app开发者的角度来看,仅仅对于androi ...
- Java面试题:写代码使得分别出现StackOverflowError和OutOfMemoryError
转载自:http://www.cnblogs.com/xudong-bupt/p/3360206.html 今天做了个笔试,这是其中的一道题目:写代码使得分别出现StackOverflowError和 ...
- 【Java面试题】32 ArrayList和Vector的区别
1. Vector & ArrayList 相同点: 1.ArrayList和Vector都是继承了相同的父类和实现了相同的接口 2.底层都是数组实现的 3.初始默认长度都为10. 不同点: ...
随机推荐
- ADB 基础命令使用
1.adb shell(>=2个设备显示:error: more than one device/emulator,仅连接一个设备可用) adb -d shell 只运行在真实设备中 adb - ...
- SQL Server 2008收缩日志文件--dbcc shrinkfile参数说明
原文:SQL Server 2008收缩日志文件--dbcc shrinkfile参数说明 DBCC SHRINKFILE 收缩相关数据库的指定数据文件或日志文件大小. 语法 DBCC SHRINKF ...
- SignalR--Web客户端
原文:SignalR--Web客户端 这里说web客户端其实是JavaScript起的作用,也可以说是JavaScript客户端. 官方的标题的JavaScript客户端. 下面的翻译,同样的代码的形 ...
- 利用BLCR加速android的启动(zygote加入checkpoint支持)
目前基于android4.2.2基线代码的blcr扩展,编译和启动是没有问题了,但是一重启就挂了. 弄这个有段时间了,很纠结,没有个可靠的结果,但是研究到现在,又舍不得放弃. 我想除了shuaiwen ...
- Linux iostat
转自 http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858810.html Linux IO实时监控iostat命令详解 简介 iostat ...
- Linux下卸载QT SDK
unbuntu下卸载QT方法一:you can remove it like this, those developers should add this somewhere ! like next ...
- 为什么不用C++写游戏(聪明的程序员不用C++折磨自己)(这些工作,QT都替开发者解决了,C++没有根类导致太多的问题,也没有字符串类)
当今世界上绝大多数游戏都是C++写的,为什么要说不呢? 要做什么?写游戏. 写游戏首先要考虑些什么?做什么样的游戏,图形.音效.游戏逻辑如何实现. 用C++要先考虑什么?定义跨平台数据类型抽象,实现常 ...
- PHP阿里大鱼短信验证
PHP阿里大鱼短信验证 第一步 登陆阿里大于注册账号,在用户管理中心创建应用,确定AppKEY和App Secret还有配置签名 第二步 在应用管理中选择SDK下载,或者直接点击http://down ...
- 简单介绍几种Java后台开发常用框架组合
01 前言 Java框架一直以来都是面试必备的知识点,而掌握Java框架,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能对当前正在开发中的系统有整体的认知,从而更好的熟悉和学习技术,这篇 ...
- 确认过眼神,看清HTTP协议
导读:什么是 HTTP?它有什么属性?我们常用的是什么呢?快来阅读本文,将会为你一一道来. 什么是 HTTP 协议? 在了解HTTP之前,我们需要了解什么是网络通信模型(也就是我们常说的 OSI 模型 ...