Iterator介绍
设计理念
- 迭代器可以提供统一的迭代方式
- 迭代器也可以在对客户端透明的情况下,提供各种不同的迭代方式。
- 迭代器提供一种快速失败机制,防止多线程下迭代的不安全操作。
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
? An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways:
- Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
- Method names have been improved.
成员
使用示例
使用Iterator遍历集合
@Test
public void testIterator(){
List<String> list = new ArrayList<String>();
list.add("TEST1");
list.add("TEST2");
list.add("TEST3");
list.add("TEST4");
list.add("TEST6");
list.add("TEST5");
Iterator<String> it = list.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
运行结果
使用迭代器remove
@Test
public void testIteratorRemove(){
List<String> list = new ArrayList<String>();
list.add("TEST1");
list.add("TEST2");
list.add("TEST3");
list.add("TEST4");
list.add("TEST5");
list.add("TEST6");
Iterator<String> it = list.iterator();
try{
it.remove();
}catch (Exception e){
e.printStackTrace();
}
it.next();
it.next();
it.remove();
try{
it.next();
list.add("TEST7");
it.remove();
}catch (Exception e){
e.printStackTrace();
}
list.forEach(System.out::println);
}
运行结果
自定义迭代器
class StringIterator implements Iterable<String> {
protected String[] sentence = ("this is a string iterator").split(" ");
public Iterator<String> iterator() {
return new Iterator<String>() {
private int index = 0;
public boolean hasNext() {
return index < sentence.length;
}
public String next() {
return sentence[index++];
}
public void remove() {
}
};
}
}
@Test
public void testMyIterator() {
for (String s : new StringIterator()) {
System.out.print(s + ",");
}
}
运行结果
Spliterator
设计
- An object for traversing and partitioning elements of a source. The source of elements covered by a Spliterator could be, for example, an array, a Collection, an IO channel, or a generator function.
A Spliterator may traverse elements individually (tryAdvance()) or sequentially in bulk (forEachRemaining()). - Spliterator may also partition off some of its elements (using trySplit) as another Spliterator, to be used in possibly-parallel operations.
- A Spliterator also reports a set of characteristics() of its structure, source, and elements from among ORDERED,DISTINCT,SORTED , SIZED, NONNULL, IMMUTABLE, CONCURRENT, and SUBSIZED. These may be employed by Spliterator clients to control, specialize or simplify computation.
- Spliterator that does not report IMMUTABLE or CONCURRENT is expected to have a documented policy concerning: when the spliterator binds to the element source; and detection of structural interference of the element source detected after binding.
- Spliterators can provide an estimate of the number of remaining elements via the estimateSize method.
- Despite their obvious utility in parallel algorithms, spliterators are not expected to be thread-safe; instead, implementations of parallel algorithms using spliterators should ensure that the spliterator is only used by one thread at a time.
- Primitive subtype specializations of Spliterator are provided for int, long, and double values.
注意
- 常用集合的character
- 类似CopyOnWriteArrayList是Immutable的
- 类似ConcurrentHashMap是Concurrent的
- binding
- The mutable source provides a late-binding and fail-fast Spliterator.
成员
boolean tryAdvance(Consumer<? super T> action);
- If a remaining element exists, performs the given action on it, returning true; else returns false.
- Params: action – The action
- Throws: NullPointerException – if the specified action is null
default void forEachRemaining(Consumer<? super T> action)
- Performs the given action for each remaining element, sequentially in the current thread, until all elements have been processed or the action throws an exception.
- If this Spliterator is ORDERED, actions are performed in encounter order.
Spliterator<T> trySplit();
- If this spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.
- If this Spliterator is ORDERED, the returned Spliterator must cover a strict prefix of the elements.
- Unless this Spliterator covers an infinite number of elements, repeated calls to trySplit() must eventually return null. Upon non-null return:
- the value reported for estimateSize() before splitting, must, after splitting, be greater than or equal to estimateSize() for this and the returned Spliterator
- if this Spliterator is SUBSIZED, then estimateSize() for this spliterator before splitting must be equal to the sum of estimateSize() for this and the returned Spliterator after splitting.
- Returns: a Spliterator covering some portion of the elements, or null if this spliterator cannot be split
long estimateSize();
- Returns an estimate of the number of elements that would be encountered by a forEachRemaining traversal, or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.
- f this Spliterator is SIZED and has not yet been partially traversed or split, or this Spliterator is SUBSIZED and has not yet been partially traversed, this estimate must be an accurate count of elements that would be encountered by a complete traversal.
- Otherwise, this estimate may be arbitrarily inaccurate, but must decrease as specified across invocations of trySplit.
使用示例
tryAdvance
@Test
public void testTryAdvance(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
Spliterator<Integer> spliterator = list.spliterator();
while(spliterator.tryAdvance(System.out::println));
}
运行结果
并行遍历
static class SpliteratorThread<T> extends Thread {
private Spliterator<T> spliterator;
public SpliteratorThread(Spliterator<T> spliterator) {
this.spliterator = spliterator;
}
@Override
public void run() {
if (spliterator != null) {
spliterator.forEachRemaining((item) ->{
System.out.println(Thread.currentThread().getName() + item);
});
}else {
System.out.println("spliterator is null");
}
}
}
@Test
public void testConcurrentAdvance(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
Spliterator<Integer> spliterator0 = list.spliterator();
Spliterator<Integer> spliterator1 = spliterator0.trySplit();
Spliterator<Integer> spliterator2 = spliterator1.trySplit();
Thread t0 = new SpliteratorThread<>(spliterator0);
t0.setName("thread-0: ");
Thread t1 = new SpliteratorThread<>(spliterator1);
t1.setName("thread-1: ");
Thread t2 = new SpliteratorThread<>(spliterator2);
t2.setName("thread-2: ");
t0.start();
t1.start();
t2.start();
}
运行结果
|