迭代器

迭代器(Iterator)

用于遍历某个数据结构实例中的所有数据,它取代了java集合框架中的Enumeration接口的位置

  • 与Enumeration接口比较,迭代器的优点在于:
    • ①增加了可以在遍历过程中进行删除操作的
    • ②方法名进行了改进(感觉没什么卵用)

查看源码,发现其中的remove()方法和forEachRemaining()方法使用了default关键字

//代码清单:
 default void remove() {
        throw new UnsupportedOperationException("remove");
    }

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

查阅资料显示:dufault关键字允许对接口中的方法进行实现,当子类继承该接口时,可以选择直接使用已经实现的方法,也可以选择自己实现,打破了对接口的惯性认知。

另外也出现了Consumer接口,查看源码。

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

可以比较容易的了解到:Consumer接口主要用于抽取不同类中存在的对对象相同的动作,例如一个自然数类,实数类和一个复数类都包含加减乘除等操作,为减少代码量,我们可以抽取这些共有的操作到多个Consumer接口(加法接口、减法接口、乘法接口、除法接口)中并实现,而在类中只需定义一个传入Consumer类型参数的方法即可。

而与Consumer接口相似的还有Function接口,代码如下

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
  • Function与consumer接口的区别在于:
    Function中的二次操作(compose)是对同一个对象进行两次相同的apply,而Consumer中的二次操作(andThen)是对同一个对象进行两此不同的操作,因此andThen方法还需传入一个Consumer类型参数

Spliterator

分割迭代器,用于对集合对象进行切分并记录切入点,最终目的是为了并行遍历被分割的元素。

下面是一个二分法分割迭代器

	class TaggedArray<T> {
	    private final Object[] elements; // immutable after construction
	    TaggedArray(T[] data, Object[] tags) {
	      int size = data.length;
	      if (tags.length != size) throw new IllegalArgumentException();
	      this.elements = new Object[2 * size];
	      for (int i = 0, j = 0; i < size; ++i) {
	        elements[j++] = data[i];
	        elements[j++] = tags[i];
	      }
	    }
 
    public Spliterator<T> spliterator() {
      return new TaggedArraySpliterator<>(elements, 0, elements.length);
    }
 
    static class TaggedArraySpliterator<T> implements Spliterator<T> {
      private final Object[] array;
      private int origin; // current index, advanced on split or traversal
      private final int fence; // one past the greatest index
 
      TaggedArraySpliterator(Object[] array, int origin, int fence) {
        this.array = array; this.origin = origin; this.fence = fence;
      }
 
      public void forEachRemaining(Consumer<? super T> action) {
        for (; origin < fence; origin += 2)
          action.accept((T) array[origin]);
      }
 
      public boolean tryAdvance(Consumer<? super T> action) {
        if (origin < fence) {
          action.accept((T) array[origin]);
          origin += 2;
          return true;
        }
        else // cannot advance
          return false;
      }
 
      public Spliterator<T> trySplit() {
        int lo = origin; // divide range in half
        int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
        if (lo < mid) { // split out left half
          origin = mid; // reset this Spliterator's origin
          return new TaggedArraySpliterator<>(array, lo, mid);
        }
        else       // too small to split
          return null;
      }
 
      public long estimateSize() {
        return (long)((fence - origin) / 2);
      }
 
      public int characteristics() {
        return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
      }
   }

需要尝试进行多线程编程测试,有时间再说了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值