章
目
录
ArrayList.spliterator()
返回 Spliterator
的实例,它是最后绑定的且具有快速失败(fail-fast)特性。Java Spliterator
用于遍历和分割源中的元素,例如数组、Set、List 或 IO 通道。
1.ArrayList spliterator() 方法
1.1. 方法定义
对于 ArrayList,spliterator()
方法返回 ArrayListSpliterator
类的实例,它是 ArrayList 的内部类并实现了 Spliterator
接口。
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
static final class ArrayListSpliterator<E> implements Spliterator<E> {
//implementation
}
Spliterator
是快速失败的,这意味着在绑定发生后,对元素的任何干扰都会被检测到,从而抛出 ConcurrentModificationException
。
1.2. 特征
ArrayList 返回的 Spliterator
具有以下特征:
- ORDERED – 表示在遍历和分割时元素具有定义的顺序。
- SORTED – 表示元素遵循预定义的排序顺序。
- SUBSIZED – 表示此 Spliterator 和任何进一步生成的 Spliterator 都是 SIZED 的。这里的 SIZED 意味着 Spliterator 是从具有已知大小的源创建的。
2.ArrayList spliterator() 示例
Spliterator
可用于许多用例。以下是一些示例:
2.1. tryAdvance() – 逐个遍历元素
Java 程序使用 Spliterator
逐个遍历元素的示例。这相当于 Iterator
接口的 next()
方法。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Spliterator;
public class ArrayListExample
{
public static void main(String[] args)
{
ArrayList<Integer> digits = new ArrayList<>(Arrays.asList(1,2,3,4,5,6));
Spliterator<Integer> sItr = digits.spliterator();
sItr.tryAdvance( d -> System.out.println( d ) );
sItr.tryAdvance( d -> System.out.println( d ) );
sItr.tryAdvance( d -> System.out.println( d ) );
}
}
输出:
1
2
3
2.2. forEachRemaining() – 遍历所有元素
Java 程序遍历所有元素并对它们执行操作的示例。这相当于在循环中使用 Iterator
的 hasNext()
方法和 next()
方法。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Spliterator;
public class ArrayListExample
{
public static void main(String[] args)
{
ArrayList<Integer> digits = new ArrayList<>(Arrays.asList(1,2,3,4,5,6));
Spliterator<Integer> sItr = digits.spliterator();
sItr.tryAdvance( d -> System.out.println( d ) ); //1
sItr.tryAdvance( d -> System.out.println( d ) ); //2
sItr.forEachRemaining( d -> System.out.println( d ) ); //3,4,5,6
}
}
输出:
1
2
3
4
5
6
2.3. trySplit() – 并行处理
如果您正在开发并发应用程序并且列表具有大量元素,那么将列表分成两部分并并行处理是个好主意。
trySplit()
方法将当前的 Spliterator
拆分成两个,并返回一个新的 Spliterator
。它正在指向的元素被分成两个相等的列表。
请记住,个别 Spliterator
默认情况下不是线程安全的。创建不同的线程并交给它们 Spliterator
实例是应用程序代码的责任。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Spliterator;
public class ArrayListExample
{
public static void main(String[] args)
{
ArrayList<Integer> digits = new ArrayList<>(Arrays.asList(1,2,3,4,5,6));
Spliterator<Integer> sItr1 = digits.spliterator();
Spliterator<Integer> sItr2 = sItr1.trySplit();
System.out.println(sItr1.getExactSizeIfKnown()); //3
sItr1.forEachRemaining( d -> System.out.println( d ) ); //4,5,6
System.out.println("===========");
System.out.println(sItr2.getExactSizeIfKnown()); //3
sItr2.forEachRemaining( d -> System.out.println( d ) ); //1,2,3
}
}
输出:
3
4
5
6
===========
3
1
2
3
3. 迭代器Iterator和Spliterator的区别
Iterator | Spliterator |
---|---|
从 Java 1.2 开始。 | 从 Java 8 开始。 |
可用于循环访问所有集合类。 | 可用于迭代数组、stream、list 和set,但不支持map |
不支持并行处理。 | 支持并行处理。 |
这就是 Java 中的 ArrayList.spliterator()
方法的全部内容。