ArrayList的底层是长度可动态变化的数组,其适用于查找多,修改少的情况,原因是数组的元素的增加删除元素会涉及大量元素的移动,效率比较低,ArrayList中的元素可以重复,与插入时的顺序相同,可以为null,继承自AbstractList,对Collection接口中的部分方法做了实现,实现了List接口,List接口中的方法都需要在ArrayList中进行实现,实现了RandomAccess、Cloneable、java.io.Serializable可以实现克隆,可以实现序列化、反序列化。

首先创建一个类,创建一个数组和size属性。

private Object[] elementData;
private int size; public MyArrayLIst(){
this(5);
}
//初始化
public MyArrayLIst(int size) {
this.elementData = new Object[size];
this.size = 0;
}

获取ArrayList的元素个数:

/**
* 获取元素个数
*/
public int size() {
return size;
}

添加元素:涉及到当前的数组是否满需要扩容的情况,即满则扩容

/**
* 添加元素
*/
public boolean add(T value) {
//满则扩容
if (size == elementData.length) {
elementData = Arrays.copyOf(elementData, elementData.length * 2);
}
elementData[size] = value;
size++;
return true;
}

通过下标获取某个元素:应该判断其参数的合法性

/**
* 获取元素
*/
public T get(int index) {
T data = (T) new Object();
if (index >= size || index < 0) {
throw new RuntimeException("参数不合法");
} else {
data = (T) elementData[index];
}
return data;
}

删除元素:删除元素涉及到元素的移动,便需要将删除元素的后面所有元素向前移动

/**
* 删除元素
*/
public boolean remove(int index) {
if (index >= size || index < 0) {
throw new RuntimeException("参数不合法");
} else {
for (int i = index; i < size; i++) {
//元素的移动
elementData[i] = elementData[i + 1];
}
elementData[size - 1] = null;//便于GC的回收
size--;
} return true;
}

要实现Iterator的接口,便需要自定义的ArrayList实现Iterable接口 ,重写他的Iterator方法,实现一个内部类并且重写Iterator的接口,其中包含三个主要的方法

boolean  hasNext()

判断 iterator 内是否存在下1个元素,如果存在,返回true,否则返回false。

Object next()

返回 iterator 内下1个元素,同时上面的指针向后移动一位。
故,如果不断地循环执行next()方法,就可以遍历容器内所有的元素了。

void remove()

删除 iterator 内指针的前1个元素,前提是至少执行过1次next();
(这个方法不建议使用,建议使用容器本身的romove 方法)。

 @Override
public Iterator<T> iterator() {
return new str();
}

由于其返回的是一个对象,便需要创建一个内部类,来实现其中的方法,代码如下:

 class str implements Iterator<T>{
int i;
public str(){
i = 0;
}
@Override
public boolean hasNext() { return i++ < size;
} @Override
public T next() {
if(false){
}
return (T)elementData[i-1];
} @Override
public void remove() { }
}

代码改进:

class str implements Iterator<T>{
private int nextIndex;
private int index;
public str(){
nextIndex = 0;
index = -1; //如果初始数组为空 就不用判断一号位置是否有元素
}
@Override
public boolean hasNext() {
return nextIndex < size;
} @Override
public T next() {
int i = nextIndex;
T value = (T)elementData[i];
nextIndex++;
index = i;
return value ; } @Override
public void remove() {
MyArrayLIst.this.remove(index);
nextIndex = index;
index = -1;
}
}

具体的完整代码如下:

import java.util.Arrays;
import java.util.Iterator; public class MyArrayLIst<T> implements Iterable<T>{
private Object[] elementData;
private int size; public MyArrayLIst(){
this(5);
}
//初始化
public MyArrayLIst(int size) {
this.elementData = new Object[size];
this.size = 0;
} /**
* 添加元素
*/
public boolean add(T value) {
//满则扩容
if (size == elementData.length) {
elementData = Arrays.copyOf(elementData, elementData.length * 2);
}
elementData[size] = value;
size++;
return true;
} /**
* 获取元素
*/
public T get(int index) {
T data = (T) new Object();
if (index >= size || index < 0) {
throw new RuntimeException("参数不合法");
} else {
data = (T) elementData[index];
}
return data;
} /**
* 获取元素个数
*/
public int size() {
return size;
} /**
* 删除元素
*/
public boolean remove(int index) {
if (index >= size || index < 0) {
throw new RuntimeException("参数不合法");
} else {
for (int i = index; i < size; i++) {
//元素的移动
elementData[i] = elementData[i + 1];
}
elementData[size - 1] = null;//便于GC的回收
size--;
} return true;
} @Override
public Iterator<T> iterator() {
return new str();
} // class str implements Iterator<T>{
// int i;
// public str(){
// i = 0;
// }
// @Override
// public boolean hasNext() {
//
// return i++ < size;
// }
//
// @Override
// public T next() {
// if(false){
// }
// return (T)elementData[i-1];
// }
//
// @Override
// public void remove() {
//
// }
// }
class str implements Iterator<T>{
private int nextIndex;
private int index;
public str(){
nextIndex = 0;
index = -1; //如果初始数组为空 就不用判断一号位置是否有元素
}
@Override
public boolean hasNext() {
return nextIndex < size;
} @Override
public T next() {
int i = nextIndex;
T value = (T)elementData[i];
nextIndex++;
index = i;
return value ; } @Override
public void remove() {
MyArrayLIst.this.remove(index);
nextIndex = index;
index = -1;
}
} public static void main(String[] args) {
MyArrayLIst<Integer> myArrayLIst = new MyArrayLIst<>();
myArrayLIst.add(9);
myArrayLIst.add(8);
myArrayLIst.add(1);
myArrayLIst.add(2);
myArrayLIst.add(3);
myArrayLIst.add(5); System.out.println(myArrayLIst.size());
System.out.println(myArrayLIst.get(4)); // myArrayLIst.remove(1);
// System.out.println(myArrayLIst.get(1));
Iterator iterator = myArrayLIst.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}

测试如图:

 

补充:

一个迭代器实例只能使用一次,如果要再次使用迭代器,便要创建一个新的迭代器实例。

												

自定义实现的ArrayList以及自定义实现的Iterator迭代器的更多相关文章

  1. java 16 -11 ArrayList存储自定义对象并增强for遍历

    需求:ArrayList存储自定义对象并遍历.要求加入泛型,并用增强for遍历. A:迭代器 B:普通for     C:增强for LinkedList,Vector,Colleciton,List ...

  2. Java基础知识强化之集合框架笔记24:ArrayList存储自定义对象并遍历

    1. ArrayList存储自定义对象并遍历 2. 代码示例: Student.java,如下: package cn.itcast_01; public class Student { privat ...

  3. Java基础六(自定义类、ArrayList集合)

    今日内容介绍1.自定义类型的定义及使用2.自定义类的内存图3.ArrayList集合的基本功能4.随机点名器案例及库存案例代码优化 ###01引用数据类型_类 * A: 数据类型 * a: java中 ...

  4. 06_Java基础语法_第6天(自定义类、ArrayList集合)_讲义

    今日内容介绍 1.自定义类型的定义及使用 2.自定义类的内存图 3.ArrayList集合的基本功能 4.随机点名器案例及库存案例代码优化 01引用数据类型_类 * A: 数据类型 * a: java ...

  5. Java基础语法(自定义类、ArrayList集合)

    Java基础语法 今日内容介绍 u 自定义类 u ArrayList集合 第1章 引用数据类型(类) 1.1 引用数据类型分类 提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类 ...

  6. Android自定义视图三:给自定义视图添加“流畅”的动画

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  7. 制作自定义背景Button按钮、自定义形状Button的全攻略(转)

    在Android开发应用中,默认的Button是由系统渲染和管理大小的.而我们看到的成功的移动应用,都是有着酷炫的外观和使用体验的.因此,我们在开发产品的时候,需要对默认按钮进行美化.在本篇里,笔者结 ...

  8. 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组

    利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...

  9. Hadoop案例(五)过滤日志及自定义日志输出路径(自定义OutputFormat)

    过滤日志及自定义日志输出路径(自定义OutputFormat) 1.需求分析 过滤输入的log日志中是否包含xyg (1)包含xyg的网站输出到e:/xyg.log (2)不包含xyg的网站输出到e: ...

随机推荐

  1. HDU 2066最短路径Dijkstra、

    思路:枚举所有起点城市然后比较每个起点所去喜欢城市的最小距离 #include<cstdio> #include<cmath> #include<cstring> ...

  2. [转]Jmeter压力测试工具安装及使用教程

    一.Jmeter下载 进入官网:http://jmeter.apache.org/ 1.第一步进入官网如下图 2.选择进行下载,下载下来为一个压缩包,解压即可. 3.我下载的是jmeter4.0版本, ...

  3. 原 在windows上创建文件名以“.”开头的文件

    在实际项目开发中,我们会经常遇到以”.”开头的配置文件.例如我们如果需要通过配置文件给npm更换源就需要更改.npmrc文件,然而还有很多友友还不清楚如何创建一个类似的文件,今天就和大家分享下这个小技 ...

  4. JavaScript DOM查询,原生js实现元素子节点的获取

    在网页网页开发中,经常会需要获取某个网页元素的子元素,然后对其进行事件绑定.或样式修改等行为.这些操作对于jquery来说很容易,但是对于原生js会稍微麻烦一些,这里将介绍四种方法获取元素的子元素(本 ...

  5. 2018-12-25-WPF-如何在-WriteableBitmap-写文字

    title author date CreateTime categories WPF 如何在 WriteableBitmap 写文字 lindexi 2018-12-25 09:13:57 +080 ...

  6. background:url(./images.png) no-repeat 0 center的用法

    background:url(./images.png) no-repeat 0 center; //图像地址 不重复 水平位置0 垂直位置居中 background:url(./images.png ...

  7. 2018-2-13-git-合并两个仓库

    title author date CreateTime categories git 合并两个仓库 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23:3 ...

  8. onload事件属性,JQ中的load,ready方法

    onload事件属性,JQ中的load,ready方法 前言 页面中的很多操作,需要我们在所需资源下载完成后,才可以进行操作,而资源没有及时下载,我们进行操作的话,是会报错.因此我们需要熟练掌握哪些事 ...

  9. C++Review1_多态和虚函数

    继承是实现多态的基础.虚函数是实现多态的方法.虚函数.多态.继承都是紧密相关的概念.而继承是所有概念的基础: 多态:简单来讲就是接口一样,实现多样.多态是指通过基类的指针或者引用,在运行时动态调用实际 ...

  10. Xcode崩溃日志分析工具symbolicatecrash用法

    1.什么是symbolicatecrash? symbolicatecrash是Xcode自带的一个分析工具,可以通过机器上的崩溃日志和应用的.dSYM文件定位发生崩溃的位置,把crash日志中的一堆 ...