首先简单回顾一下ArrayList
特点:在内存中分配连续的空间,只存储数据,不存储地址信息,位置就隐含地址。
底层结构:一个长度可以动态增长的数组
优点:1.节省存储空间,因为分配给数据的存储单元,全都用来存放节点的数据,节点之间的逻辑关系并没有占用额外的空间
2.索引查询效率高,每一个节点对应一个序号,该序号可以通过计算公式得到节点地址(通俗来说 一个长度为5的数组 首节点的地址为100 ,那么一个节点占用4个字节,第4个节点的地址即为100+4x4=116)
缺点:1.增加删除效率低,需要一个一个的位移元素
2.必须提前分配固定数量的空间 ,如果存储数据少了就造成空间的浪费
3.按照内容查询效率低 因为需要一个一个比较
通过无参构造方法创建对象时 JDK7默认给定长度为10 ,JDK8默认给的长度为0,添加元素时在给长度 10
长度不够时每次扩容50% 扩容原理:当空间不足时会创建一个新的数组 默认长度是之前长度的2倍,然后把原数组的内容拷贝到新的数组中 在把地址指向原数组
好了,废话不多说上代码了(***如果代码有问题的话,请留言!!!***)
先创建一个模拟需要实现的接口
/**
* 模拟list实现接口
*/
public interface List {
// 返回线性表的大小,即数据元素的个数。
public int size();
// 返回线性表中序号为 i 的数据元素 根据下标获取元素
public Object get(int i);
// 如果线性表为空返回 true,否则返回 false。判断是否为空
public boolean isEmpty();
// 判断线性表是否包含数据元素 e 判断集合中是否包含某元素
public boolean contains(Object e);
// 返回数据元素 e 在线性表中的序号 返回指定元素的下标
public int indexOf(Object e);
// 将数据元素 e 插入到线性表中 i 号位置 插入到指定下标的位置
public void add(int i, Object e);
// 将数据元素 e 插入到线性表末尾 添加元素
public void add(Object e);
// 将数据元素 e 插入到元素 obj 之前 将指定元素插入到标记元素之前
public boolean addBefore(Object obj, Object e);
// 将数据元素 e 插入到元素 obj 之后 将指定元素插入到标记元素之后
public boolean addAfter(Object obj, Object e);
// 删除线性表中序号为 i 的元素,并返回之 删除指定下标的元素
public Object remove(int i);
// 删除线性表中第一个与 e 相同的元素 删除第一个元素为e 的数据
public boolean remove(Object e);
// 替换线性表中序号为 i 的数据元素为 e,返回原数据元素 替换下标中的元素为指定元素
public Object replace(int i, Object e);
public Iterator iterator(); //实现迭代器
}
创建迭代器接口
public interface Iterator<T> {
boolean hasNext();
T next();
}
实现ArratList接口中的常用方法
/**
* 实现ArrayList 相关功能
*/
public class ArrayList implements List {
private transient Object[] elementData; //ArrayList底层是一个长度可以动态增长的数组
private int size = 0; //集合中元素的个数,不是数组分配了多少个空间
public ArrayList(){
//this(10);//JDK7的原理
elementData=new Object[10];
}
public ArrayList(int initialCapacity){
if(initialCapacity<0){
throw new IllegalArgumentException("输入的参数不能小于0: "+initialCapacity);
}
elementData=new Object[initialCapacity];
}
/**
* 获取数组长度
* @return
*/
@Override
public int size() {
return size;
}
/**
* 获取指定下标的元素值
* @param i 指定下标
* @return
*/
@Override
public Object get(int i) {
if(i<0||i>=size){
throw new RuntimeException("数组索引越界异常:"+i);
}
return elementData[i];
}
/**
* 判断数组是否为空
* @return
*/
@Override
public boolean isEmpty() {
return size==0;
}
/**
* 判断数组中是否包含某元素
* @param e 指定元素
* @return
*/
@Override
public boolean contains(Object e) {
return indexOf(e)!=1;
}
/**
* 根据指定元素 返回该元素在数组中的下标
* @param e
* @return
*/
@Override
public int indexOf(Object e) {
int index=-1;//表示不存在
for (int i=0;i<size;i++){
if(elementData[i].equals(e)){
index=i;
break;
}
}
return index;
}
/**
* 添加元素到指定的下标处
* @param i
* @param e
*/
@Override
public void add(int i, Object e) {
//如果数组长度满了 扩充
if (size==elementData.length){
elementData= Arrays.copyOf(elementData,size*2);
}
//后移后面的元素
for(int index = size-1; index >=i; index-- ){
elementData[index+1] = elementData[index];
}
//添加元素
elementData[i]=e;
//数组长度自增
size++;
}
/**
* 添加元素到数组末尾
* @param e
*/
@Override
public void add(Object e) {
//如果数组长度满了需要扩容
if(size==elementData.length){
// //创建一个新的数组 数组的长度是原数组的长度的2倍
// Object[] newArray=new Object[size*2];
// //把原数组中的元素拷贝到新数组中
// for (int i = 0; i <size; i++) {
// newArray[i]=elementData[i];
// }
// //把新数组指定给原数组
// elementData=newArray;
elementData= Arrays.copyOf(elementData,size*2);//优化上面数据
}
//添加元素到数组末尾
elementData[size]=e;
//数组长度自增
size++;
}
/**
* 添加元素到数组某个元素之前
* @param obj
* @param e
* @return
*/
@Override
public boolean addBefore(Object obj, Object e) {
return false;
}
/**
* 添加元素到标记元素之后
* @param obj
* @param e
* @return
*/
@Override
public boolean addAfter(Object obj, Object e) {
return false;
}
/**
* 根据指定下标删除指定元素
* @param i
* @return
*/
@Override
public Object remove(int i) {
return null;
}
/**
* 根据元素值删除数组中第一个值为e的元素
* @param e
* @return
*/
@Override
public boolean remove(Object e) {
return false;
}
/**
* 根据指定的下标替换为指定的元素
* @param i
* @param e
* @return
*/
@Override
public Object replace(int i, Object e) {
return null;
}
/**
* 实现迭代器
* @return
*/
@Override
public Iterator iterator() {
return new Itr();
}
/**
* 重写toStirng
* @return
*/
@Override
public String toString() {
StringBuilder stringBuilder=new StringBuilder("[");
for (int i=0;i<=size-1;i++){
stringBuilder.append(elementData[i]+",");
}
if(size>0){
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
stringBuilder.append("]");
return stringBuilder.toString();
}
//使用内部类,可以直接访问外部类的成员变量
private class Itr<T> implements Iterator<T> {
int cursor =0;//默认值是0,用来指向当前元素,默认指向第0个
@Override
public boolean hasNext() {
return cursor<size;
}
@Override
public T next() {
int i = cursor;
if(i>=size){
throw new NoSuchElementException("没有这个元素了,cursor:"+i);
}
cursor++;
return (T)elementData[i];
}
}
}
测试方法
public class Test {
public static void main(String[] args) {
List list = new ArrayList();
//向末尾添加元素
list.add("11111");
list.add("aaaaa");
list.add("bbbbb");
list.add("33333");
list.add("22222");
list.add(3, "AAAAA");
//进行各种操作验证添加
System.out.println(list.get(3));
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.contains("11111"));
System.out.println(list.indexOf("22222"));
System.out.println(list.toString());
Iterator<String> it = list.iterator();
while(it.hasNext()){
String elem = it.next();
System.out.println(elem);
}
}
}