Java分离器(Spliterator)示例
时间:2020-01-09 10:34:59 来源:igfitidea点击:
与Iterator和ListIterator一样,Java中的Spliterator用于遍历源元素。它与其他迭代器实现的不同之处在于,除顺序遍历外,Spliterator API还设计为支持有效的并行遍历。使用Spliterator元素可以并行进行分区和迭代。
有关Java Spliterator的要点
- 使用Spliterator接口定义了Spliterator API,该接口是java.util包的一部分。
- 在Java 8中添加了Spliterator接口。
- 分离器的源可以是数组,集合,IO通道或者生成器函数。
- 分离器可用于并行遍历和顺序遍历。
- 当使用Iterator进行遍历时,必须使用两种方法-hasNext()以确保存在下一个元素next()方法来使用该元素。 Java Spliterator中的方法将这两种方法合二为一,使用起来更加方便。
Java Spliterator方法
Spliterator API定义了以下方法。
- features()–返回此分隔符及其元素的一组特征。
- EstimateSize()–返回元素数量的估计值,如果无限,未知或者计算成本太高,则返回Long.MAX_VALUE。
- forEachRemaining(Consumer <?super T> action)–在当前线程中依次对每个剩余元素执行给定的操作,直到所有元素都已处理或者该动作引发异常。
- getComparator()–如果该分隔器的源由比较器排序,则返回该比较器。
- getExactSizeIfKnown()-如果此Spliterator为SIZED,则返回估计方法size()的便捷方法,否则为-1.
- hasCharacteristics(int features)–如果此Spliterator的features()包含所有给定的特征,则返回true。
- tryAdvance(Consumer <?super T> action)–如果存在剩余元素,则对其执行给定的操作,返回true;否则,返回true。否则返回false。
- trySplit()–使用此方法,分隔符可以分为两个。返回一个覆盖元素的新Spliterator,从此方法返回后,当前的Spliterator将不覆盖该元素。
Java分离器特性
分隔符还定义了以下特征,这些特征是恒定的int值。
- CONCURRENT –特征值,表示元素源可以由多个线程安全地并发修改,而无需外部同步。
- DISTINCT –特征值,表示对于每对遇到的元素x,y,!x.equals(y)。
- IMMUTABLE –表示无法对元素源进行结构修改的特征值。
- NONNULL –特征值,表示源保证所遇到的元素不会为空。
- ORDERED –表示已为元素定义相遇顺序的特征值。
- SIZED –特征值,表示从estimateSize()返回的值是元素的精确计数。
- 已排序–表示遇到顺序遵循已定义排序顺序的特征值。
- SUBSIZED –特征值,表示所有trySplit()产生的Splitter都将被SIZED和SUBSIZED。
Java Spliterator示例
让我们看一些示例,以了解如何使用Spliterator进行遍历以及如何使用其方法。
使用Spliterator的tryAdvance()方法进行遍历
public class SpliteratorTraversal { public static void main(String[] args) { List<String> listOfNames = Arrays.asList("Clint", "Gregory", "James", "John", "Humphrey", "Cary", "Kirk"); Spliterator<String> spliterator = listOfNames.spliterator(); System.out.println("--- Names in the list ---"); while(spliterator.tryAdvance(System.out::println)); spliterator = listOfNames.spliterator(); System.out.println("--- Names in the list in upper case ---"); while(spliterator.tryAdvance(n -> System.out.println(n.toUpperCase()))); } }
输出:
--- Names in the list -- Clint Gregory James John Humphrey Cary Kirk --- Names in the list in upper case -- CLINT GREGORY JAMES JOHN HUMPHREY CARY KIRK
使用estimateSize(),getExactSizeIfKnown(),forEachRemaining()方法的示例
public class SpliteratorTraversal { public static void main(String[] args) { List<String> listOfNames = Arrays.asList("Clint", "Gregory", "James", "John", "Humphrey", "Cary", "Kirk"); Spliterator<String> spliterator = listOfNames.spliterator(); System.out.println("Estimated Size of source- " + spliterator.estimateSize()); System.out.println("Exact Size of source- " + spliterator.getExactSizeIfKnown()); System.out.println("--- Names in the list in upper case ---"); spliterator.forEachRemaining(n -> System.out.println(n.toUpperCase())); } }
输出:
Estimated Size of source- 7 Exact Size of source- 7 --- Names in the list in upper case -- CLINT GREGORY JAMES JOHN HUMPHREY CARY KIRK
使用trySplit()Java示例进行拆分
public class SpliteratorTraversal { public static void main(String[] args) { List<String> listOfNames = Arrays.asList("Clint", "Gregory", "James", "John", "Humphrey", "Cary", "Kirk"); Spliterator<String> split1 = listOfNames.spliterator(); Spliterator<String> split2 = split1.trySplit(); // checking if spliterator is actually split if(split2 != null) { System.out.println("Partition- "); while(split2.tryAdvance((n) -> System.out.println(n))); } System.out.println("Partition- "); while(split1.tryAdvance((n) -> System.out.println(n))); } }
输出:
Partition- Clint Gregory James Partition- John Humphrey Cary Kirk