使用Java 8聚合操作处理IO流

来源:互联网 发布:亚马逊大数据应用 编辑:程序博客网 时间:2024/05/16 10:53

如何使用Java 8的聚合操作(Stream)处理IO流

目前只研究了java.io.*的相关操作,对于nio暂时没有研究


Oracle在2014年发布了Java 8。Oracle在该版本中添加了许多新特性,包括Lambda表达式、方法引用、加强了安全等等。聚合操作(Aggregate> Operations)也是一个重大的特色。

一般Aggregate Operations(聚合操作)也被称作流。一般被用于集合(Collection)的处理上,如配合lambda表达式,可以简单的通过如以下代码可以实现快速的排序并输出功能。

list.stream().sorted().forEach(System.out::println)

在此说明聚合操作的效率,目前开来,不一定比使用传统的方法有速度上的优势,但是其在一行代码中可以实现诸多操作,并且思路清晰易懂的特点,完全可以“秒杀”传统方式。当需要修改代码时,非常方便的定位到要修改的部分。


说重点

本文主要介绍聚合操作超高效处理文本文件的IO。以作者实现的从批量文件中读取文本并统计单词为例。
* 直接上干货

    Stream.of(readers).flatMap(f->f.lines())    .flatMap(line -> Stream.of(line.split("\\W"))).    distinct().sorted().forEach(System.out::println);

其中readers是已经打开的BufferedReader对象的一个数组
那么为什么用Reader数组呢,因为不知道流会不会自动关闭打开的文件,为了防止没有关文件,希望有验证了的童鞋告诉我(我觉得可能会关闭,只是猜测)。如果不考虑关闭的影响的话,完全可以这样。

    Stream.of(fileNames).map(FileReader::new).map(BufferedReader::new)    .flatMap(f->f.lines()).flatMap(line -> Stream.of(line.split("\\W"))).    distinct().sorted().forEach(System.out::println);

可以想象如果用传统的方式要怎么处理:

    Set set = new TreeSet();    for(String fileName : files){        BufferedReader reader = new BufferedReader(new FileReader(fileName));        String l;        while((l = reader.readLine()) != null){                set.addAll(Arrays.asList(l.split("\\W")));        }        reader.close();    }    set.forEach(System.out::println);

那么问题来了那现在我要修改成统计每个单词出现的频率,对于传统方式基本上要来一次大手术。而对于聚合操作,请看大招

HashMap<String,Integer> map = Stream.of(readers).flatMap(f->f.lines()).    flatMap(line -> Stream.of(line.split("\\W")))    .collect(HashMap::new,(m,word) -> m.compute(word,(k,v)->v==null?1:v+1),HashMap::putAll );

传统方式要怎么改呢?。。。。想想都头大!


总结

其实就是BufferedReader里面有个lines可以生成一个以每行为元素的Stream。

0 0