自定义实现的ArrayList以及自定义实现的Iterator迭代器
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迭代器的更多相关文章
- java 16 -11 ArrayList存储自定义对象并增强for遍历
需求:ArrayList存储自定义对象并遍历.要求加入泛型,并用增强for遍历. A:迭代器 B:普通for C:增强for LinkedList,Vector,Colleciton,List ...
- Java基础知识强化之集合框架笔记24:ArrayList存储自定义对象并遍历
1. ArrayList存储自定义对象并遍历 2. 代码示例: Student.java,如下: package cn.itcast_01; public class Student { privat ...
- Java基础六(自定义类、ArrayList集合)
今日内容介绍1.自定义类型的定义及使用2.自定义类的内存图3.ArrayList集合的基本功能4.随机点名器案例及库存案例代码优化 ###01引用数据类型_类 * A: 数据类型 * a: java中 ...
- 06_Java基础语法_第6天(自定义类、ArrayList集合)_讲义
今日内容介绍 1.自定义类型的定义及使用 2.自定义类的内存图 3.ArrayList集合的基本功能 4.随机点名器案例及库存案例代码优化 01引用数据类型_类 * A: 数据类型 * a: java ...
- Java基础语法(自定义类、ArrayList集合)
Java基础语法 今日内容介绍 u 自定义类 u ArrayList集合 第1章 引用数据类型(类) 1.1 引用数据类型分类 提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类 ...
- Android自定义视图三:给自定义视图添加“流畅”的动画
这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...
- 制作自定义背景Button按钮、自定义形状Button的全攻略(转)
在Android开发应用中,默认的Button是由系统渲染和管理大小的.而我们看到的成功的移动应用,都是有着酷炫的外观和使用体验的.因此,我们在开发产品的时候,需要对默认按钮进行美化.在本篇里,笔者结 ...
- 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组
利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...
- Hadoop案例(五)过滤日志及自定义日志输出路径(自定义OutputFormat)
过滤日志及自定义日志输出路径(自定义OutputFormat) 1.需求分析 过滤输入的log日志中是否包含xyg (1)包含xyg的网站输出到e:/xyg.log (2)不包含xyg的网站输出到e: ...
随机推荐
- laravel .env 文件的使用
转载地址 http://www.cnblogs.com/Eden-cola/p/DotEnv-in-lumen.html umen 是 laravel 的衍生品,核心功能的使用和 laravel 都 ...
- Codeforces3C. Tic-tac-toe 题解 状态压缩+搜索
作者:zifeiy 标签:状态压缩.搜索 题目链接:https://codeforces.com/contest/3/problem/C 题目大意: 有一个 \(3 \times 3\) 的棋盘,给你 ...
- Javassist指引(一)
目录 原文链接 1. 读写字节码 1.1概述 Javassist是一个Java字节码类库.Java的字节码是包含Java类与接口,并按照一定的顺序存在class文件中. Javassist.CtCla ...
- H3C Basic NAT配置示例
- java构造方法的私有化
有的时候我们为了避免外界创建某类的实例,就将某类的构造方法私有化,即将它的构造方法用private修饰: 外界如何用到? 提供get方法!不提供的话外界就没法创建对象!(对反射无效) Eg:packa ...
- js基础——变量、作用域、内存
1.new关键字创建的是引用类型: eg. var box = new Object(); box.name = "Linda";//引用类型添加属性没问题 al ...
- spring security (BCryptPasswordEncoder)加密及判断密码是否相同
通过BCryptPasswordEncoder的加密的相同字符串的结果是不同的,如果需要判断是否是原来的密码,需要用它自带的方法. 加密: BCryptPasswordEncoder encode = ...
- win10 uwp 发布旁加载自动更新
在很多企业使用的程序都是不能通过微软商店发布,原因很多,其中我之前的团队开发了很久的应用,结果发现没有用户能从微软应用商店下载所以我对应用商店没有好感.但是作为一个微软粉丝,怎么能不支持 UWP 开发 ...
- 5款顶尖Windows文件传输工具
5款顶尖Windows文件传输工具 英文原文: Drasko 日常工作中,公司里的系统管理员或其他岗位的员工都需要传递大量各种类型的文件和文档.其中一些可以通过 email 收发.但由于 email ...
- maven仓库总结,maven私服搭建,批量mvn eclipse:eclipse
配置pom.xml依赖包时在这里找包的描述: http://search.maven.org/#browse 以java为根目录. mvn archtype:generate -DgroupId=zt ...