Interable接口

Iterable接口是Collection的父接口,主要用于遍历Collection集合中的元素。

方法如下:

//使用迭代器进行遍历
Iterator<T> iterator();
//使用Lambda表达式进行遍历
default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}
//可切割遍历
default Spliterator<T> spliterator() {
    return Spliterators.spliteratorUnknownSize(iterator(), 0);
}

1. Iterator接口

Iterator接口:迭代器,迭代器的作用主要是遍历集合中的元素,所以Iterator对象必须依附于Collection对象

常用方法:
boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回true
Object.next():返回集合里的下一个元素
void remove():删除集合里上一次next方法返回的元素
void forEachRemaining(Consumer action):该方法为java8新增的默认方法,该方法可使用Lambda表达式来遍历集合元素

注意:

  • 迭代器遍历期间,不能删除集合中的元素,否则出发快速失败(fail-fast)机制,出现异常ConcurrentModificationException

  • 迭代时如果只是删除倒数第二个元素,不会报错,但是不建议这样操作。

  • 对同一个迭代器对象只能使用一种方法的迭代方式,另一种将会被覆盖

  • 不要多次使用it.next(),每次使用都是访问下一个对象,如果一个对象元素内包含了多个数据,则多次使用取数据,数据是错开的

  • 迭代器是接口的原因:

    • 因为集合类的数据结构不同,所以在存储的时候就不同,所以导致遍历的方式也不一样

    • 最终就只能将迭代器定义成接口,使各种类去自己实现,保证了正确性

    • 迭代器在具体实现类中以内部类的形式存在

package com.carl.javaadvanced.collection_demo;

import java.util.*;

public class ListTest {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(10);
        list.add("java");
        list.add(true);
        //使用迭代器遍历集合中的元素--三种方法
        //方法1:
        Iterator iterator=list.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
            if (next.equals(10)) {
                list.remove(next);//ConcurrentModificationException
            }

        }
        //方法2:
        //1.能用while循环写迭代程序,能不能用for循环?能,for循环效率高,因为用完的迭代器就成了垃圾
        for(Iterator it=c.iterator();it.hasNext();) {
            String s=(String)it.next();
            System.out.println(s);
        }
        //方法3:
        //forEachRemaining方法:Lamdba表达式遍历
        iterator.forEachRemaining(obj-> System.out.println("forEachRemaining方法:"+obj));
        //这种方式和Iterable接口中的forEach是一样的
    }
}

2. Spliterator接口

Spliterator:可拆分迭代器,用于遍历容器中的元素,并拆分,然后并行处理

这里的容器可以是:数组、集合、IO通道、生成器函数

在JDK8.0以后,集合框架中所包含的所有数据结构都提供了默认的Spliterator实现

常用方法:
boolean tryAdvance(Consumer<? super T> action);//逐个处理元素--调用一次处理一个元素,处理lambda表达式

default void forEachRemaining(Consumer<? super T> action);//批量处理元素,循环tryAdvance()方法

Spliterator<T> trySplit();//对Spliterator进行分割,返回一个新的Spliterator可拆分迭代器

long estimateSize();//计算剩余多少元素需要遍历,使用tryAdvance和forEachRemaining遍历过的元素不会计算在内

default long getExactSizeIfKnown();//当迭代器拥有SIZED特征,返回剩余元素个数,否则返回-1

int characteristics();//返回当前对象有哪些**特征值**

default boolean hasCharacteristics(int characteristics);//是否具有characteristics特征值

default Comparator<? super T> getComparator();//如果Spliterator的list是通过Comparator排序,则返回Comparator对象
                                              //如果Spliterator的list是通过自然排序,则返回null

特征值如下

特征十六进制十进制含义
ORDERED0x0000001016元素之间是有顺序的
DISTINCT0x000000011元素之间不会重复
SORTED0x000000044元素遵循定义的排序顺序
SIZED0x0000004064表示长度为有限个
NONNULL0x00000100256表示元素不能为空
IMMUTABLE0x000004001024元素源不能修改(不能添加,替换或删除元素)
CONCURRENT0x000010004096多个线程安全同时修改元素源而无需外部同步
SUBSIZED0x0000400016384迭代器所分割得到的子迭代器也是有序的

原子类型的规范接口

在这里插入图片描述

Spliterator定义了三个原子类型的规范,分别是OffInt,OffLong,OffDouble,通过OfPrimitive封装了统一方法。OffInt通过引用IntConsumer来消费遍历的元素,OffLong通过LongConsumer来消费,OffDouble通过DoubleConsumer来消费。通过这种方式减少了装箱带来的性能消耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Carl·杰尼龟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值