使用流计算值的百分比
Calculate percentage of a value using stream
我正在尝试弄清楚如何在使用 stream
时计算列表中特定值的百分比。
我的对象 getTag
可以取值 G
或 Y
,我想计算 G:s
在列表中的百分比。另一个对象是 getDateTime
,其形式为 1946-01-12
。
我有条件 filter(weather -> !weather.getDateTime().isAfter(dateTo) && !weather.getDateTime().isBefore(dateFrom))
因为我只想要用户输入的两个日期之间的百分比。
因此每个 DateTime 值对应于 G
或 Y
。我用Collectors.counting()
计算了G
和Y
的频率,但是我怎样才能得到百分比?
Map<String, Long> percentage = weatherData.stream()
.filter(weather -> !weather.getDateTime().isAfter(dateTo) && !weather.getDateTime().isBefore(dateFrom))
.collect(Collectors.groupingBy(Weather::getTag, Collectors.counting()));
如果将您关心的项目 ("G") 映射为 1,将其他所有项目映射为 0,则平均值为 "G" 在流中的百分比。
double pctG = list.stream()
.mapToInt(obj -> obj.getTag().equals("G") ? 1 : 0)
.summaryStatistics()
.getAverage();
和Java13,可以用teeing()
收集器按tag统计元素,和过滤后的元素总数,整理将组数除以总数:
Map<String, Double> fractions = weatherData.stream()
.filter(...)
.collect(
Collectors.teeing(
Collectors.groupingBy(Weather::getTag, Collectors.counting()),
Collectors.counting(),
YourClass::scale));
其中 scale()
函数将每个组除以总数:
static <T> Map<T, Double> scale(Map<? extends T, Long> counts, long total) {
return counts.entrySet().stream().
.collect(Collectors.toMap(e -> e.getKey(), ((double) e.getValue()) / total));
}
我正在尝试弄清楚如何在使用 stream
时计算列表中特定值的百分比。
我的对象 getTag
可以取值 G
或 Y
,我想计算 G:s
在列表中的百分比。另一个对象是 getDateTime
,其形式为 1946-01-12
。
我有条件 filter(weather -> !weather.getDateTime().isAfter(dateTo) && !weather.getDateTime().isBefore(dateFrom))
因为我只想要用户输入的两个日期之间的百分比。
因此每个 DateTime 值对应于 G
或 Y
。我用Collectors.counting()
计算了G
和Y
的频率,但是我怎样才能得到百分比?
Map<String, Long> percentage = weatherData.stream()
.filter(weather -> !weather.getDateTime().isAfter(dateTo) && !weather.getDateTime().isBefore(dateFrom))
.collect(Collectors.groupingBy(Weather::getTag, Collectors.counting()));
如果将您关心的项目 ("G") 映射为 1,将其他所有项目映射为 0,则平均值为 "G" 在流中的百分比。
double pctG = list.stream()
.mapToInt(obj -> obj.getTag().equals("G") ? 1 : 0)
.summaryStatistics()
.getAverage();
和Java13,可以用teeing()
收集器按tag统计元素,和过滤后的元素总数,整理将组数除以总数:
Map<String, Double> fractions = weatherData.stream()
.filter(...)
.collect(
Collectors.teeing(
Collectors.groupingBy(Weather::getTag, Collectors.counting()),
Collectors.counting(),
YourClass::scale));
其中 scale()
函数将每个组除以总数:
static <T> Map<T, Double> scale(Map<? extends T, Long> counts, long total) {
return counts.entrySet().stream().
.collect(Collectors.toMap(e -> e.getKey(), ((double) e.getValue()) / total));
}