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 的行为
配合方法 characteristics
、hasCharacteristics
使用
接口定义方法
接口定义方法 |
---|
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
}
}