Java8 的一些新特性的学习理解

  近期在学习队列相关的一些知识,在学习过程中发现Iterable<T>接口中新增了两个新的方法,出于好奇,就想知道这是什么东东,干什么用的。俗话说:实践出真知,所以就有了以下反复的测试。

先看下新增的这两个方法:

1 default void forEach(Consumer<? super T> action) {
2     Objects.requireNonNull(action);
3     for (T t : this) {
4         action.accept(t);
5     }
6 }
1 default Spliterator<T> spliterator() {
2      return Spliterators.spliteratorUnknownSize(iterator(), 0);
3 }


都知道接口中是不能写实现方法的哈,但是它这却有了实现方法,忽然间觉得世界观都被颠覆了,其实呢这也是java8新增的一个特性,在接口方法中添加default关键字就可以直接在接口中写实现(这不是本文的重点,感兴趣的童鞋可以自行学习java8)。

下面正式开始测试<使用BlockingQueue测试>:

1 BlockingQueue<Integer> q = new ArrayBlockingQueue<Integer>(1024);
2 while(q.size()<10){
3     q.put(q.size()+1);
4 }
5 Spliterator<Integer> split = q.spliterator();
6 split.forEachRemaining(line->{System.out.println(line);});  //①
7 System.out.println("-------------------------------------");
8 split.forEachRemaining(line->{System.out.println(line);}); //②

以上输出结果为:

1
2
3
4
5
6
7
8
9
10
-------------------------------------

根据以上结果可以看出,②处并没有输出任何的数据。看下Spliterator提供的迭代类forEachRemaining,它是为了并行处理流而新增的一个迭代类,

源码:

1 default void forEachRemaining(Consumer<? super T> action) {
2       do { } while (tryAdvance(action));
3 }

tryAdvance方法则对下一个为处理的操作执行action并返回true, 如果没有下一个元素,返回false。

 1 public boolean tryAdvance(Consumer<? super T> action) {
 2       if (action == null) throw new NullPointerException();
 3        if (it == null) {
 4            it = collection.iterator();
 5            est = (long) collection.size();
 6        }
 7       if (it.hasNext()) {
 8           action.accept(it.next());
 9           return true;
10       }
11       return false;
12 }

根据上面的源码可以看出,action如果为空直接抛出异常。it为空时,it是遍历传入集合的Iterator对象。

所以在①处:调用了迭代调用了tryAdvance,执行完①之后,it已经指向了conllection的最后一项,而对于②处,传入的集合是同一个集合,对于it也已经指向了最后一项,所以返回了false,没有数据可输出。

 

trySplit:ArrayListSpliterator的trySplit采用二分法,将前一半数据返回, 如果数据太小不能分了,返回null。而ConcurrentLinkedQueue和ConcurrentLinkedDeque的相应的Spliterator处理稍微复杂一点, 第一次取一个,第二个取两个,不超过MAX_BATCH。

 更多的功能还需要慢慢的学习。

posted @ 2015-11-03 10:48  xiao_quan  阅读(320)  评论(0编辑  收藏  举报