当前位置: > 论文中心 > 计算机论文 >

浅析Java 8中的集合遍历(3)

时间:2014-10-23 16:58 点击:
请注意清单4中的被动迭代与前面三个清单中的主动迭代之间的差异。在主动迭代中由循环结构控制迭代,并且每次通过循环从列表中获取一个对象,然后打印出来。而在清单4中没有显式的循环结构,我们只是告诉forEach()

  请注意清单4中的被动迭代与前面三个清单中的主动迭代之间的差异。在主动迭代中由循环结构控制迭代,并且每次通过循环从列表中获取一个对象,然后打印出来。而在清单4中没有显式的循环结构,我们只是告诉forEach()方法对列表中的对象实施打印,迭代控制隐含在forEach()方法中。

  3.2 流

  如果要做一些比打印名字稍微复杂一点的事情,比如,计算以字母A开头的人名的个数,就需要用lambda表达式,或者使用Java 8的流API(Stream API)来实现更复杂的逻辑了。

  流是应用在一组元素上的一次执行的操作序列。集合和数组都可以用来产生流,因此它们称作数据源,但流不存储集合中的元素,相反,流是通过管道(pipeline)操作来自数据源的值序列的一种机制。流管道(Stream Pipeline)由数据源(Stream Source)、若干中间操作(Intermediate Operations)和一个最终操作(Terminal Operation)组成,中间操作对数据集完成过滤、检索等中间业务,而最终操作完成对数据集处理的最终结果,或者调用forEach()方法。

  List names = new LinkedList<>();

  names.add("Annie");

  names.add("Alice");

  names.add("Bob");

  long count = names.stream()

  .filter(name -> name.startsWith("A")

  .count();

  代码清单5:Java8使用流管道计算以字母A开头的人名的

  个数

  List names = new LinkedList<>();

  names.add("Annie");

  names.add("Alice");

  names.add("Bob");

  long count = 0;

  for (String name : names){

  if (name.startsWith("A"))

  ++count;

  }

  代码清单6:Java 7使用主动迭代计算以字母A开头的人

  名的个数

  如清单5所示,列表names用于创建流,然后使用过滤器对数据集进行过滤,filter()方法只过滤出以字母A开头的名字,该方法的参数是一个lambda表达式[2]。最后,流的count()方法作为最终操作,得到应用结果。

  中间操作除了filter()之外,还有distinct()、sorted()、map()等等,其一般是对数据集的整理(过滤、排序、匹配、抽取等等),返回值一般也是数据集。

  最终方法往往是完成对数据集中数据的处理,如forEach(),还有allMatch()、anyMatch()、findAny()、findFirst(),数值计算类的方法有sum()、max()、min()、averag()等等。最终方法也可以是对集合的处理,如reduce()、collect()等等。reduce()方法的处理方式一般是每次都产生新的数据集,而collect()方法是在原数据集的基础上进行更新,过程中不产生新的数据集。流管道操作更为详细的资料请参阅Java Tutorial[3]。

  为了理解Java8的流的重要性,请比较代码清单5和代码清单6。代码清单6是大多数Java开发人员比较熟悉的,它使用主动式迭代完成同样的功能。很显然,只要掌握了流的基本概念和操作,清单5中的方法易读性更好且不易出错,特别是,在多线程环境下清单6中的逻辑不是线程安全的,而清单5是线程安全的,它也更容易进行并行化。

  Java8集合类不仅具有Stream()方法,该方法返回一个连续的数据流,Java8集合类还有一个parallelStream()方法,该方法返回一个并行流。并行流的作用在于允许管道操作同时在不同的Java线程中执行以提高性能;但要注意,集合元素的处理顺序可能发生改变。测试显示,使用并行流打印列表中的名字,他们打印的顺序不同于他们在列表中出现的顺序。下面是使用并行流之后的代码:

  long count=names.parallelStream().filter(name-> name.startsWith("A")).count();

  4 性能比较(Performance comparison)

  虽然使用Java 8中的被动迭代器有多种优势,那么它是否提供更快的集合处理速度呢?为了比较主动迭代器、流和并行流的性能,下面我们还是以计算字母A开头的人名的个数为例,采取上述三种迭代方法做一个比较测试。在一台双核奔腾处理器、4G内存、64位Windows 7和64位版本的Java 8配置环境下,使用五种不同的集合类(LinkedList,ArrayList、HashSet、LinkedHashSet和TreeSet)运行上述程序,将平均时间总结在如下所示的表1中。

  5 结论(Conclusion)

  Java 8支持一种新功能进行迭代,它是声明性的方法,这种新方法带来的好处是代码的可读性更好,不易出错,也更容易并行化。然而测试表明,并行流对每一种集合类而言不一定性能更快。

   论文榜(www.zglwb.com),是一个专门从事期刊推广、投稿辅导的网站。
本站提供如何投稿辅导,寻求投稿辅导代理,快速投稿辅导,投稿辅导格式指导等解决方案:省级投稿辅导/国家级投稿辅导/核心期刊投稿辅导//职称投稿辅导。


栏目列表
联系方式
推荐内容
 
QQ在线咨询
投稿辅导热线:
189-6119-6312
微信号咨询:
18961196312