【JDK源码】Iterator和Spliterator

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.

成员

  • boolean hasNext();:Returns true if the iteration has more elements

  • E next();:

    • Returns: the next element in the iteration
    • Throws: NoSuchElementException – if the iteration has no more elements
  • default void remove():

    • Removes from the underlying collection the last element returned by this iterator

    • Throws:

      • UnsupportedOperationException – if the remove operation is not supported by this iterator
      • IllegalStateException – if the next method has not yet been called, or the remove method has already been called after the last call to the next method
    • default implementation:

          default void remove() {
              throw new UnsupportedOperationException("remove");
          }
      
  • default void forEachRemaining(Consumer<? super E> action):

    • Performs the given action for each remaining element until all elements have been processed or the action throws an exception

    • Actions are performed in the order of iteration, if that order is specified.

    • Params:

      • action – The action to be performed for each element
    • Throws:

      • NullPointerException – if the specified action is null
    • default implementation

          default void forEachRemaining(Consumer<? super E> action) {
              Objects.requireNonNull(action);
              while (hasNext())
                  action.accept(next());
          }
      

使用示例

使用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();

        // it.remove 必须在it.next之后执行
        try{
            it.remove();
        }catch (Exception e){
            e.printStackTrace();
        }
        it.next();
        it.next();
        // remove the 2rd element
        it.remove();

        // 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();
}
运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pass night

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值