20221201 java.util.Spliterator

java.util.Spliterator

基本信息

  • public interface Spliterator<T>
  • rt.jar
  • 引入版本:8
  • 相关类:
    • java.util.Collection
    • java.lang.Iterable
    • java.util.Spliterators :工具类

使用说明

  • 可分割迭代器
  • 并行遍历
  • 配合并行流在底层执行,一般不需要自己实现

静态常量

静态常量
public static final int ORDERED = 0x00000010;
顺序
public static final int DISTINCT = 0x00000001;
非重复
public static final int SORTED = 0x00000004;
排序
public static final int SIZED = 0x00000040;
数量
public static final int NONNULL = 0x00000100;
非空
public static final int IMMUTABLE = 0x00000400;
不可修改
public static final int CONCURRENT = 0x00001000;
可并发
public static final int SUBSIZED = 0x00004000;
子 Spliterator 都将是 SIZED

这些常量定义的是 Spliterator 的特征,可以组合使用

某些特征值不能兼容,如果同时具有,那么不能保证 Spliterator 的行为

配合方法 characteristicshasCharacteristics 使用

接口定义方法

接口定义方法
boolean tryAdvance(Consumer<? super T> action);
如果存在剩余元素,则对其执行给定的操作,返回 true ;否则返回 false 。
如果此 Spliterator 是 ORDERED ,则按遇到顺序对下一个元素执行操作。
default void forEachRemaining(Consumer<? super T> action)
在当前线程中按顺序对每个剩余元素执行给定操作,直到处理完所有元素或操作引发异常。如果此 Spliterator 是 ORDERED ,则将按遇到顺序执行操作。
Spliterator<T> trySplit();
对 Spliterator 进行拆分
long estimateSize();
返回 forEachRemaining 遍历将遇到的元素数量的估计值,或者如果无限、未知或计算成本太高则返回 Long.MAX_VALUE 
如果具有特征 SIZED 或 SUBSIZED ,必须返回准确数量
default long getExactSizeIfKnown()
如果此 Spliterator 为 SIZED 则返回 estimateSize() 的结果,否则返回 -1
int characteristics();
返回具有的特征值
default boolean hasCharacteristics(int characteristics)
判断是否具有特征值
default Comparator<? super T> getComparator()
如果具有特征 SORTED ,返回相应的 Comparator ;
如果是自然排序,返回 null 
如果不具有特征 SORTED ,抛出异常 IllegalStateException

示例代码

package study.hwj._spliterator;

import cn.hutool.core.collection.ListUtil;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.Spliterator;
import java.util.TreeSet;
import java.util.stream.IntStream;

/**
 * _spliterator
 *
 * @author owenwjhuang
 * @date 2022/12/1
 */
public class Test1 {
    @Test
    public void testBinary() {
        System.out.println(0b10);   // 2, 2进制表示法
        System.out.println(010);    // 8, 8进制表示法
        System.out.println(10);     // 10, 10进制表示法
        System.out.println(0x10);    // 16, 16进制表示法

        System.out.println(Integer.toBinaryString(0x10));   // 10000, 数字转2进制
        System.out.println(Integer.toOctalString(10));      // 12, 数字转2进制
        System.out.println(Integer.toHexString(10));        // 10000, 数字转2进制
    }

    @Test
    public void testCharacteristics() {
        ArrayList<Integer> arrayList = new ArrayList<>();
        Spliterator<Integer> spliterator = arrayList.spliterator();
        System.out.println(spliterator.characteristics());      // 16464 ,十进制表示,没什么意义
        System.out.println(
                Integer.toHexString(spliterator.characteristics()));     // 十六进制表示,对比Spliterator里的静态常量,使用加法,可以知道具有哪些特征
        System.out.println(spliterator.hasCharacteristics(Spliterator.SIZED));
        System.out.println(spliterator.hasCharacteristics(Spliterator.SUBSIZED));
        System.out.println(spliterator.hasCharacteristics(Spliterator.ORDERED));
        // 参考代码验证 java.util.ArrayList.ArrayListSpliterator.characteristics


    }


    @Test
    public void testComparator() {
        ArrayList<Integer> arrayList = new ArrayList<>();
        Spliterator<Integer> spliterator = arrayList.spliterator();
        // Comparator<? super Integer> comparator = spliterator.getComparator();   // 抛出异常

        SortedSet<Integer> sortedSet = new TreeSet<>();
        Comparator<? super Integer> comparator1 = sortedSet.spliterator().getComparator();
        System.out.println(comparator1);    // null
    }

    @Test
    public void testIterate() {
        ArrayList<Integer> arrayList = ListUtil.toList();
        for (int i = 0; i < 100; i++) {
            arrayList.add(i);
        }
        Spliterator<Integer> spliterator = arrayList.spliterator();

        spliterator.tryAdvance(System.out::println);    // 0

        System.out.println("****************************");

        spliterator.forEachRemaining(System.out::println);      // 1-99
    }

    @Test
    public void testSplit() {
        ArrayList<Integer> arrayList = ListUtil.toList();
        for (int i = 0; i < 100; i++) {
            arrayList.add(i);
        }
        Spliterator<Integer> spliterator = arrayList.spliterator();

        Spliterator<Integer> subSpliterator = spliterator.trySplit();
        subSpliterator.forEachRemaining(System.out::println);       // 0-49

        System.out.println("****************************");

        spliterator.forEachRemaining(System.out::println);          // 50-99
    }

    @Test
    public void testParallel() {
        IntStream.range(0, 100).parallel().peek(System.out::println).count();
        // 通过断点调试,发现执行到了方法
        // java.util.stream.Streams.RangeIntSpliterator.trySplit
    }


}

参考资料

posted @ 2022-12-01 10:04  流星<。)#)))≦  阅读(65)  评论(0编辑  收藏  举报