有同学问如何使用stream统计单词数。这是个好例子,也很典型,在这里补上。
下面的例子实现了从一个文本文件读取(英文)文本并统计单词数的功能。
package com.imooc;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* 使用stream统计文章单词数
*
* @author 晓风轻
*
*/
public class StreamWordDemo {
public static void main(String[] args) throws IOException {
// 使用try-resource 关闭资源
try (BufferedReader reader = new BufferedReader(
new FileReader(webflux.txt))) {
long wordCount = reader.lines()
// trim前后空格(使用方法引用)
.map(String::trim)
// 过滤掉空串
.filter(s - !s.isEmpty())
// 把空格隔开的转为单词数组
.map(s - s.split( ))
// 得到数组长度
.mapToInt(array - array.length)
// 并行(都是无状态操作)
.parallel()
// 求和
.sum();
System.out.println(单词数: + wordCount);
}
}
}
牵涉的知识点主要还是lambda表达式和stream的基本应用。大家可以看出,使用stream编程代码非常清晰和简单,可读性很强。
下面获取每个单词出现的次数
// 使用try-resource 关闭资源
try (BufferedReader reader = new BufferedReader(
new FileReader(webflux.txt))) {
MapString, Long counts = reader.lines()
// trim前后空格(使用方法引用)
.map(String::trim)
// 过滤掉空串
.filter(s - !s.isEmpty())
// 把空格隔开的转为数组
.map(s - s.split( ))
// 数组转成流
.map(array - Stream.of(array))
// 拉平
.flatMap(stream - stream)
// 分组
.collect(Collectors.groupingBy(s - s, Collectors.counting()));
System.out.println(单词出现次数: + counts);
// 统计信息
LongSummaryStatistics summaryStatistics = counts.entrySet().stream()
// 得到次数
.mapToLong(entry - entry.getValue())
// 统计
.summaryStatistics();
System.out.println(统计信息: + summaryStatistics);
}
输出的统计信息为:
统计信息:LongSummaryStatistics{count=170, sum=271, min=1, average=1.594118, max=14}
可以看出,一共有271个单词,不同的词有170个,出现最多的14次,最少1次,平均1.594118次。
这就是stream的编程风格,其中lambda表达式是函数式编程的基础,是后面的stream,reactor的前置基础知识。