may*_*ʎɐɯ 10 java lambda java-8 java-stream
我有一个单词列表文本文件,我想从该文件中获取最小,最大和平均单词长度.
我有一个流方法:
public static Stream<String> readWords(String filename) {
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
Stream<String> stringStream = reader.lines();
return stringStream;
} catch (IOException exn) {
return Stream.<String>empty();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的主要测试方法中,我打印最大和最小
System.out.println(readWords(filename)
.min(Comparator.comparing(s -> s.length()))
.get()
.length()
);
System.out.println(readWords(filename)
.max(Comparator.comparing(s -> s.length()))
.get()
.length()
);
Run Code Online (Sandbox Code Playgroud)
它按预期工作.
问题:
是否有可能像我在min和max中那样得到单词长度的平均值?在是或否的情况下,如何做到这一点(仅作为Lambda表达式)?
rge*_*man 13
该lines()
方法将为您提供线条流,而不是单词.一旦你有了Stream
,调用flatMap
用单词替换行,提供lambda表达式来拆分单词:
Stream<String> stringStream = reader.lines().flatMap( line ->
Stream.of(line.split("\\s+"))
);
Run Code Online (Sandbox Code Playgroud)
这将纠正你的max
和min
.的实现.它还会影响您希望实施的任何平均计算的正确性.
要获得平均值,您可以调用mapToInt
将单词流映射到它们的长度(产生一个IntStream
),然后调用average
,返回一个OptionalDouble
.
System.out.println(readWords(filename)
.mapToInt( s -> s.length() ) // or .mapToInt(String::length)
.average()
.getAsDouble());
Run Code Online (Sandbox Code Playgroud)
使用IntSummaryStatistics
以获得最大,最小和平均一通.
IntSummaryStatistics summary = readWords(filename)
.collect(Collectors.summarizingInt(String::length));
System.out.format("min = %d, max = %d, average = %.2f%n",
summary.getMin(), summary.getMax(), summary.getAverage());
Run Code Online (Sandbox Code Playgroud)
根据有关减少的官方文件
System.out.println(readWords(filename)
.mapToInt(String::length)
.average()
.getAsDouble()
);
Run Code Online (Sandbox Code Playgroud)
请注意,您可以并且可能应该使用方法引用 String::length