java源码之Spliterator(jdk8)

前言


Spliterator是一个可分割迭代器(splitable iterator),可以和iterator顺序遍历迭代器一起看。jdk1.8发布后,对于并行处理的能力大大增强,Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator,后面我们也会结合ArrayList中的spliterator()一起解析。

方法


tryAdvance

  • jdk源码
boolean tryAdvance(Consumer<? super T> action)

单个对元素执行给定的动作,如果有剩下元素未处理返回true,否则返回false

  • demo
public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("1");
        Spliterator<String> spliterator = strings.spliterator();
        boolean flag1 =  spliterator.tryAdvance(System.out::println); 
        boolean flag2 = spliterator.tryAdvance(System.out::println); 
        System.out.println(flag1);
        System.out.println(flag2);
    }

代码在执行 boolean flag1 = spliterator.tryAdvance(System.out::println);在控制台打印了1 ,在执行System.out.println(flag1)打印了true;这表明tryAdvance获取spliterator中的元素并执行相应的操作。
代码在执行 boolean flag2 = spliterator.tryAdvance(System.out::println)控制台无打印信息,在执行System.out.println(flag2)打印了false,说明在执行tryAdvance时,会将index+1在执行元素(参照java.util.ArrayList.ArrayListSpliterator得出的结论)
spliterator.tryAdvance与iterator.hasnext和iterator.next连用有异曲同工之妙,获取元素并执行制定操作。

forEachRemaining

  • jdk源码
 default void forEachRemaining(Consumer<? super T> action) {
    do { } while (tryAdvance(action));
 }

对每个剩余元素执行给定的动作,依次处理,直到所有元素已被处理或被异常终止。默认方法调用tryAdvance方法

  • demo
public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("111");
        strings.add("112");
        Spliterator<String> spliterator = strings.spliterator();
        spliterator.forEachRemaining(System.out::println);
    }

在执行spliterator.forEachRemaining(System.out::println)时,循环输出strings下的所有元素。
从源代码可以看出,forEachRemaining其实就是对于tryAdvance的重组调用

  • 注意
    如果你先调动tryAdvance在调用forEachRemaining,那forEachRemaining不回调用tryAdvance已经调用的元素。

trySplit

  • jdk源码
 Spliterator<T> trySplit();

对原有的Spliterator分割,返回一个新的Spliterator迭代器

  • demo
public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("111");
        strings.add("112");
        Spliterator<String> spliterator = strings.spliterator();
        Spliterator<String> spliterator2 =  spliterator.trySplit();
        spliterator.forEachRemaining(System.out::println);
        spliterator2.forEachRemaining(System.out::println);
    }

代码在执行 spliterator.forEachRemaining(System.out::println)时输出112,在执行 spliterator2.forEachRemaining(System.out::println)时输出111。trySplit会将原有的Spliterator中的数据均分。原有的数据被tryAdvance或者forEachRemaining使用过的数据不会算在均分的元素中。

estimateSize

  • jdk源码
long estimateSize();

用于估算还剩下多少个元素需要遍历

  • demo
  public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("1");
        Spliterator<String> spliterator = strings.spliterator();
        System.out.println(spliterator.estimateSize());
    }

代码 System.out.println(spliterator.estimateSize())控制台打印1;
原有的数据被tryAdvance或者forEachRemaining使用过的数据不会算在计数的元素中。

getExactSizeIfKnown

  • jdk源码

 default long getExactSizeIfKnown() {
    return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
 }

当迭代器拥有SIZED特征时,返回剩余元素个数;否则返回-1

  • demo
public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("1");
        strings.add("2");
        strings.add("3");
        strings.add("4");
        Spliterator<String> spliterator = strings.spliterator();
        spliterator.tryAdvance(System.out::println);
        System.out.println(spliterator.getExactSizeIfKnown());
    }

代码System.out.println(spliterator.getExactSizeIfKnown())返回3;

characteristics

  • jdk源码
int characteristics();

返回当前对象有哪些特征值
各种特征值:

特征十六进制十进制含义
ORDERED0x0000001016元素之间是有顺序的
DISTINCT0x000000011元素之间不会重复
SORTED0x000000044元素遵循定义的排序顺序
SIZED0x0000004064表示长度为有限个
NONNULL0x00000100256表示元素不能为空
IMMUTABLE0x000004001024元素源不能修改(不能添加,替换或删除元素)
CONCURRENT0x000010004096多个线程安全同时修改元素源而无需外部同步
SUBSIZED0x0000400016384迭代器所分割得到的子迭代器也是有序的
  • demo
 public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("1");
        strings.add("2");
        strings.add("3");
        strings.add("4");
        Spliterator<String> spliterator = strings.spliterator();
        System.out.println(spliterator.characteristics());
    }

代码控制台打印结果为16464;16464=16384+64+16所以该数组有的特征值为SUBSIZED,SIZED,ORDERED。

hasCharacteristics

  • jdk源码
default boolean hasCharacteristics(int characteristics) {
    return (characteristics() & characteristics) == characteristics;
 }

是否具有当前特征值

  • demo
  public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("1");
        strings.add("2");
        strings.add("3");
        strings.add("4");
        Spliterator<String> spliterator = strings.spliterator();
        System.out.println(spliterator.hasCharacteristics(Spliterator.ORDERED));
        System.out.println(spliterator.hasCharacteristics(Spliterator.SIZED));
        System.out.println(spliterator.hasCharacteristics(Spliterator.SUBSIZED));
        System.out.println(spliterator.hasCharacteristics(Spliterator.CONCURRENT));
    }

代码执行System.out.println(spliterator.hasCharacteristics(Spliterator.ORDERED)),System.out.println(spliterator.hasCharacteristics(Spliterator.SIZED)),ystem.out.println(spliterator.hasCharacteristics(Spliterator.SUBSIZED))均返回true;在执行System.out.println(spliterator.hasCharacteristics(Spliterator.CONCURRENT))打印false。

getComparator

default Comparator<? super T> getComparator() {
     throw new IllegalStateException();
 }

如果Spliterator的list是通过Comparator排序的,则返回Comparator;如果Spliterator的list是自然排序的 ,则返回null;其他情况下抛错。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值