我有一个Map<String, Integer>
和一个名为 globalValue 的整数。我的目标是将 map 中的值替换为全局值的百分比,例如; (value1/globalValue)*100 并对最终数字进行四舍五入。
我尝试直接在映射中进行除法(结果为 0),并尝试将整数在映射内和映射外转换为 double (均导致类型不匹配)。
public Map<String, Integer> analyse() {
int globalValue = 0;
Map<String, Integer> m = new HashMap<String, Integer>();
for (int i = 0; i < array.length; i++) {
if (array[i].getTime() != null) {
globalValue = globalValue + array[i].getValue();
if (m.containsKey(array[i].getTime())) {
m.put(array[i].getTime(), m.get(array[i].getTime()) + array[i].getValue());
} else {
m.put(array[i].getTime(), array[i].getValue());
}
}
}
return m;
}
最佳答案
使用 Stream API 会简单得多。您还需要使用 double
或 Double
以避免将所有值四舍五入为 0。
public Map<String, Double> analyse() {
double sum = Stream.of(array).mapToDouble(d -> d.getValue()).sum();
return Stream.of(array)
.collect(Collectors.groupingBy(t -> t.getTime(),
Collectors.summingDouble(t -> t.getValue() * 100.0 / sum)));
}
为什么 int
值会发生这种情况?
Int division: Why is the result of 1/3 == 0?
大多数 child 在小学时学习整数除法,但一旦学习小数,似乎就忘记了。
返回整数
百分比,而不会损失太多精度。
public Map<String, Integer> analyse() {
long sum = Stream.of(array).mapToLong(d -> d.getValue()).sum();
Map<String, Long> map = Stream.of(array)
.collect(Collectors.groupingBy(t -> t.getTime(),
Collectors.summingLong(t -> t.getValue())));
return map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> (int) Math.round(100.0 * e.getValue() / sum)));
}
这可以处理许多小值加起来可达 1% 的情况。
关于java - Map<String, Integer> 获取四舍五入 int 百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53947390/