一、迭代器Iterator
迭代器是一种设计模式,提供了一种方法来对集合、容器进行遍历的方式。不需要关注底层的数据结构和数据类型,来达到底层和上层的遍历解耦的目的。
迭代器提供了三种方法,对集合进行遍历
1. boolean hasNext(); 判断集合是否还有元素,有则返回ture,没有返回false。
2. E next(); 返回下一个元素,返回当前元素的数据类型,如果到达集合结尾则抛出NoSuchElementException异常
3. void remove();删除上次访问返回的元素,删除的时候需要注意,用的不恰当会产生非法异常问题
注意:
hasNext和next出现次数一样,出现次数差为奇数会抛出空指针异常,偶数则会打印两次,hasNext和remove也是轮着出现
迭代器的实现代码:
Iterator<Integer> iterator = collection.iterator();创建一个Integer类型的迭代器
while (iterator.hasNext()) { //集合有元素则进入循环
Integer value = iterator.next(); // 将当前的值返回给value
//iterator.remove(); //删除元素
System.out.print(value + " "); //打印集合中的元素
}
返回迭代器的集合可以使用for each语句(增强for循环)处理:(实际上它的底层实现也是通过迭代器)
for (Integer i :collection) {
System.out.println(i+" ");
}
自定义迭代器:
- 需要实现Iterable接口
implements Iterable<T>
- 需要重写iterator()方法
@Override
public Iterator<T> iterator() {
return new Itr();
}
自定义迭代器代码:
//实现Iterable<T>接口
public class IteratorSelf2192<T> implements Iterable<T> {
private T[] data;//存储元素数组
private int size; //元素个数
//构造函数
public IteratorSelf2192(){
this(10); //容量
}
public IteratorSelf2192(int capacity){
if (capacity < 0){
try {
throw new IllegalAccessException("参数异常");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
data = (T[]) new Object[capacity];
size = 0;
}
//判满
public boolean isFull(){
if(data.length == size) {
return true;
}
return false;
}
//扩容 1.5倍
public void grow1(){
int newCapacity = size + (size >> 1);
data = Arrays.copyOf(data,newCapacity);
}
//下标范围判断
private boolean checkRange(int index) {
if (index< 0 || index > size)
throw new IndexOutOfBoundsException();
return true;
}
//重写toString方法
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < size;i++) {
buffer.append(data[i] + " ");
}
return buffer.toString();
}
//添加
public boolean add(T e){
if(isFull()){ //满则扩容
grow1();
}else{
data[size++] = e;
}
return true;
}
//获取
public T get(int index){
checkRange(index); //下标范围检查
return data[index];
}
//删除
public T remove(int index){
checkRange(index);
T v = data[index];
int mov = size - index -1;
System.arraycopy(data,index+1,data,index,mov); //把所删除后的数据整体向前移动一位
data[--size] = null; //最后一位置空,容量-1
return v ;
}
public boolean remove (T e) {
if (e == null) { //对象为空
for (int i = 0; i < size; i++) {
if (data[i] == null) {
int mov = size -i-1;
System.arraycopy(data, i+1, data,i,mov);
data[--size] = null;
return true;
}
}
} else { //对象非空
for (int i = 0; i < size; i++) {
if (e.equals(data[i])) {
int mov = size -i-1;
System.arraycopy(data, i+1, data,i,mov);
data[--size] = null;
return true;
}
}
}
return false;
}
@Override //重写Iterator方法
public Iterator<T> iterator() {
return new Itr();
}
class Itr implements Iterator<T>{ //内部类实现迭代器
int afterIndex; //afterindex前一个位置
int beforeIndex = -1;//beforeindex后一个位置
@Override
public boolean hasNext() { //判断集合是否还有元素 判断index是否等于size
return afterIndex != size;
}
@Override
public T next() { //返回当前位置的数据
int i = afterIndex;
if(i > size) throw new IndexOutOfBoundsException();
afterIndex+=1;
T v = data[i];
beforeIndex = i;
return v;
}
@Override
public void remove() { // 删除元素
//此处调用集合的删除方法
IteratorSelf2192.this.remove(beforeIndex);
afterIndex = beforeIndex;
beforeIndex = -1;
}
}
public static void main(String[] args) {
IteratorSelf2192<Integer> arrayList = new IteratorSelf2192<Integer>();
arrayList.add(1);
arrayList.add(4);
arrayList.add(6);
arrayList.add(2);
System.out.println(arrayList);
arrayList.remove(0); //删除0号元素
System.out.println(arrayList);
//迭代器iterator遍历打印
Iterator<Integer> iterator = arrayList.iterator();
while(iterator.hasNext()){
Integer value = iterator.next();
System.out.print(value + " ");
}
System.out.println( );
System.out.println(arrayList.size);
}
}
执行结果:
ListIterator分析:
查看源码,ListIterator中有9个方法,其中和Iterator相同的有hasNext()、next()和remove()。
常用方法使用:
- hashPrevious()、 previous():逆向遍历集合
System.out.print("previous: ");
ListIterator<Integer> listIterator1 = arrayList.listIterator(arrayList.size());
while (listIterator1.hasPrevious()) {
listIterator1.previousIndex();
System.out.print(listIterator1.previous()+" "); //逆向输出集合
}
iterator和listIterator的联系与区别?
-
ListIterator有add()方法,可以向List中添加对象,而Iterator不能
-
ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,
但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以 -
ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能
-
都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改