自定义实现的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: ...
随机推荐
- 【C++竞赛 B】yyy的回文数组
时间限制:1s 内存限制:32MB 问题描述 回文串是一个正读和反读都一样的字符串,比如level或者noon就是回文串.回文数组也是如此,比如[100,200,100]或者[178,256,256, ...
- js实现开关灯游戏
需求: 点击三个按钮,页面出现不同数量的“灯” 所有的灯有相同的点击效果.点击一个灯的时候,this和他的上下左右都会变成另一种背景色. 代码在这里~~~ 文章地址 https://www.cnblo ...
- codeforces 609B
#include<bits/stdc++.h> using namespace std; ]; int main() { memset(num,,sizeof(num)); int n,m ...
- HDU 5971"Wrestling Match"(二分图染色)
传送门 •题意 给出 n 个人,m 场比赛: 这 m 场比赛,每一场比赛中的对决的两人,一个属于 "good player" 另一个属于 "bad player" ...
- java 集合之HashMap的三种遍历
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. 这周我们只需记住三种遍历方法 1.通过keySet()获取键,再利用hashmap里面的.get(key)方法通过键获取 ...
- H3C 传递信息
- python 使用PyInstaller遇到的坑
给个链接 https://github.com/yinghualuowu/Python_VLPR/releases 参数问题 在网上随处可以见到PyInstaller的参数教程. -F : 打包成单个 ...
- springBoot中“MockMvc”的进行Controller进行单元测试:application/octet-stream' not supported问题小结
解决方案:这个问题其实是Content-type的问题,只需要在相关的代码加入相关Content-type中就可以了,代码如下: mockMvc.perform(post("/user&qu ...
- 29(30).socket网络基础
转载:https://www.cnblogs.com/linhaifeng/articles/6129246.html 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网 ...
- .data()与.detach()的区别
.data()和.detach()都可以获取Variable内部的Tensor,但.detach()更加安全 https://zhuanlan.zhihu.com/p/38475183