我正在尝试计算在“对象列表”中的某个字段中看到一个Int的次数。
这是我的代码
TreeMap<Integer, Double> ratings = new TreeMap();
ArrayList<Establishment> establishments = new ArrayList<>();
double one = 0;
double two = 0;
double three = 0;
double five = 0;
for (Establishment e : establishments) {
if (e.getRating() == 1) {
one++;
}
if (e.getRating() == 2) {
two++;
}
if (e.getRating() == 3) {
three++;
}
if (e.getRating() == 5) {
five++;
}
}
ratings.put(1, (one / establishments.size()) * 100);
ratings.put(2, (two / establishments.size()) * 100);
ratings.put(3, (three / establishments.size()) * 100);
ratings.put(5, (five / establishments.size()) * 100);
但是,这并不是理想的选择,如果添加更多的评分(例如20+),则会创建大量的双打,并且无法维护。
我知道,如果我有一个整数列表,我可以用Stream做些什么
listOfInts.stream().filter(i -> i == 3).count()
这是一个对象列表,其中包含一个整数,我需要计算该对象列表中的评级数量== X。
那么我需要的伪代码:
Establishmentemnts.getAllRatings()。stream()。filter(ratings->评分== 3).count()*
*对每种评级类型1-5重复
**没有getAllRatings-我想这就是我要解决的问题)
答案 0 :(得分:5)
您可以这样做:
Map<Integer, Double> ratings = new TreeMap<>();
List<Establishment> establishments = new ArrayList<>();
establishments.stream()
.collect(Collectors.groupingBy(Establishment::getRating, Collectors.counting()))
.forEach((k, v) -> ratings.put(k, (double)v/establishments.size() * 100));
将Collectors::groupingBy
与Collectors::counting
一起使用,这将创建一个由评分计数组成的Map
,然后使用forEach
将它们添加到{{1} }
或者,如VGR建议的那样,更优雅地使用Collectors::collectingAndThen
:
TreeMap
这将直接创建Map<Integer, Double> ratings =
establishments.stream()
.collect(
Collectors.groupingBy(Establishment::getRating,
Collectors.collectingAndThen(Collectors.counting(), c -> c * 100.0 / establishments.size())
));
,而无需创建Map
,再次对其进行流式处理,然后再次收集到Map
答案 1 :(得分:5)
仅使用或多或少的流:
List<Establishment> establishments = new ArrayList<>();
Map<Integer, Double> ratings = establishments.stream()
.collect(Collectors.groupingBy(Establishment::getRating, Collectors.counting()))
.entrySet()
.stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> 100.0 * (e.getValue() / establishments.size())));
答案 2 :(得分:3)
在这里,您可以使用流来实现getAllRatings以获得评分列表
List<Integer> attributes = establishments.stream().map(es -> es.getRating()).collect(Collectors.toList());
因此,可以使用特定等级的等级计数
establishments.stream().map(es -> es.getRating()).collect(Collectors.toList()).stream().filter(ratings -> ratings == 3).count()
如果要获取所有评分的评分计数/百分比,请使用@Marek答案中的代码
答案 3 :(得分:0)
答案 4 :(得分:-1)
循环中,您可以求和值:
for (Establishment e : establishments) {
// Get old value OR set to "0"
Double rating = ratings.getOrDefault(e.getRating(), 0);
// increase rating (counter)
ratings.put(e.getRating(), rating + 1);
}
最后计算平均值:
// Calculate part of equation which is not changing in loop
int size = establishments.size() * 100;
for (Map.Entry<Integer, Double> entry : ratings.entrySet()) {
// Calculate average
Double average = entry.getValue() / size;
// Add it to the map
ratings.put(entry.getKey(), average);
}