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