Java-04 集合框架1-Iterator/Iterable

目录

1. Iterator 与 Iterable接口的关系

2. Iterator接口

3. Iterable接口

4. Java的三种遍历方式

5. 在集合上实现自定义迭代器


1. Iterator 与 Iterable接口的关系

        Iterator是迭代器接口,可以用于迭代容器中的元素。

        Iterable是 Java 容器的最顶级的接口之一,该接口的作用是使容器具备迭代元素的功能(简而言之,就是Iterable在封装了Iterator的基础上,还提供了增强for循环的功能,foreach)。

2. Iterator接口

        也称为迭代器接口,其源代码如下所示:

 

package java.util;

import java.util.function.Consumer;

public interface Iterator<E> {
    /**
     * @return true if the iteration has more elements
     */
    boolean hasNext();

    /**
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();

    /**
     * Removes from the underlying collection the last element returned
     * by this iterator (optional operation).  
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

        · hasNext():检测容器中是否还有需要迭代的元素,有则返回true。

        · next():返回迭代器当前指向的元素(迭代器遍历),并且更新迭代器的状态,将迭代器指向的元素后移一位

        · remove():将迭代器指向的元素删除。该方法默认实现为抛出 UnsupportedOperationException 异常,如果迭代器迭代的容器不支持 remove 操作,则调用方法 remove() 时也会会抛出 UnsupportedOperationException 异常。

        · forEachRemaining():JDK 1.8 开始出现。该方法有默认实现,其作用是对容器中的剩余元素进行处理,直到剩余元素处理完毕或者抛出异常。

注意:Iterator接口中最重要的方法为 next() hasNext(),要在一个容器中实现迭代功能则必须实现next() hasNext()方法

3. Iterable接口

        Iterable接口是集合接口Collection唯一实现的接口,Iterable接口一方面封装了Iterator接口,一方面实现了增强for循环。其源代码如下:   

package java.lang;

import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;

/**
 * Implementing this interface allows an object to be the target of the enhanced
 * for statement (sometimes called the "for-each loop" statement).
 *
 * @param <T> the type of elements returned by the iterator
 */
public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type T.
     */
    Iterator<T> iterator();

    /**
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     */
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    /**
     * Creates a Spliterator over the elements described by this Iterable.
     */
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

                · Iterator():Iterator()方法是Iterable接口的核心方法,返回Iterator接口的实现类的迭代器实例。

                · forEach():从JDK1.8开始出现,默认实现是对元素中的每个元素进行处理;

                · Spliterator():从JDK1.8开始出现,默认实现是并行遍历容器中的元素;

注意:为什么有了Iterator接口以后还要有Iterable接口:

                 目的是让迭代逻辑(Iterator)与数据结构(Iterable)分离开来,这样可以通过一个数据结构实现多个迭代逻辑。即在一个Iterable接口的实现类中通过Iterator()方法的不同返回值获取多个迭代逻辑。

4. Java的三种遍历方式

        Java中提供了三种遍历方式,分别为1)普通for循环,2)迭代器遍历(要求实现Iterator接口),3)forEach循环(要求实现Iterable接口)

List<Integer> list = new ArrayList<>();
list.add(5);
list.add(23);
list.add(42);

// 普通for循环
for (int i = 0; i < list.size(); i++) {
    System.out.print(list.get(i) + ",");
}

// 迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
    System.out.print(it.next() + ",");
}
 
// forEach循环
for (Integer i : list) {
    System.out.print(i + ",");
}

5. 在集合上实现自定义迭代器

        步骤:

                1)在集合类上声明其实现了Iterable接口;

                2)重写 Iterator<T> iterator() 方法,返回一个内部类实例(要求实现Iterator接口)

                3)在内部类中添加构造方法,重写 next()、hasNext() 方法。

        实例:在顺序表SqList中实现迭代器

import java.util.Iterator;

public class SqList<T> implements Iterable<T>{             //声明SqList类使用接口Iterable<T>
    //成员变量声明
    //声明存储数据元素(泛型T)的数组
    private T[] eles;
    //声明当前顺序表中的数据元素个数
    private int N;

    //构造方法(构造器与类名相同,实例化该类的对象)
    public SqList(int capacity){
        //初始化T类型数组
        //由于java中泛型对象不能直接实例化,可以先声明一个Object数组,然后再强制转换(T[])
        this.eles = (T[])new Object[capacity];
        //初始化顺序表长度(无元素)
        this.N = 0;
    }

    //成员方法
   

    //顺序表的遍历
    //重写iterator()方法
    @Override
    public Iterator<T> iterator(){
        return new SIterator();         //返回新的内部类
    }

    //提供一个内部类SIteration,重写hasNext()&next()方法
    private class SIterator implements Iterator{
        private int cusor;
        public SIterator(){
            this.cusor = 0;
        }
        @Override
        public boolean hasNext() {
            return cusor<N;
        }

        @Override
        public Object next() {
            return eles[cusor++];
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值