java - TreeMap.higherEntry 返回一个意外的 null
问题描述
好的,所以我有这段代码应该从加权列表中获取随机条目。但是,当我尝试调用 TreeMap.higherEntry 时,即使有更高的条目可用,它也会返回 null。lowerEntry 确实有效,ceilingEntry 返回相同的 null。这是我的代码:
import java.util.*;
public class Randomizer<E> extends ArrayList<E> {
private Random rng;
private double defaultWeight;
public Randomizer(List<E> list) {
super(list);
rng = new Random();
defaultWeight = 1.0d;
}
/*Stripped some uninteresting constructor variations for clarity*/
public void setSeed(long seed) {
rng.setSeed(seed);
}
public E getRandom() {
TreeMap<Double,E> map = new TreeMap<>();
double total = 0;
for(E e : this) {
if(e instanceof Weighted) {
map.put(((Weighted) e).getWeight(),e);
total += ((Weighted) e).getWeight();
} else {
map.put(defaultWeight,e);
total += defaultWeight;
}
System.out.println(total);
}
double value = rng.nextDouble() * total;
System.out.println(value + ", " + map.higherKey(value));
return map.higherEntry(value).getValue();
}
}
这是一个小数据集的控制台输出:
5.0
9.0
11.0
14.0
15.0
15.5
19.5
22.5
24.0
26.5
27.5
28.0
9.987466924354226, null
Exception in thread "main" java.lang.NullPointerException
at me.datafox.utils.Randomizer.getRandom(Randomizer.java:52)
at me.datafox.grick.SwordTest.main(SwordTest.java:39)
有什么我做错了吗?数据集以一种非常奇怪的方式格式化,所以我将其排除在外,但很明显,从权重列表计算总数不是我面临的问题。
解决方案
javadoc说:
返回与严格大于给定键的最小键关联的键值映射,如果没有这样的键,则返回 null。
您的代码可以:
double value = rng.nextDouble() * total;
长话短说:唯一的解释是没有符合该标准的价值。换句话说:你的逻辑在这里从根本上被打破了。
关键是:您正在乘以一个随机值。所有的赌注都在这里了。有时您的代码可能会导致非空结果,有时不会。
推荐阅读
- c# - c# unity 3d坐标地图同步
- java - Java jstack 示例指向右括号而不是代码行
- c# - 列表
用于在内容控件上打印表格 - java - Resilience4j:将 Bulkhead 与 TimeLimiter 相结合,以实现来自 Tomcat 的同步外部系统调用
- javascript - 你能在 JavaScript 文件中包含一个 jQuery 库吗?
- ruby-on-rails - 防止 Rails 尝试将资产管道用于文件夹 /public/images 中的图像
- vb.net - 从 Excel 导入 .xls 和 .xlsx 版本的数据表
- arrays - 快速将一维数组转换为二维数组
- python - 如何在 TI cl2000 编译器中使用 python cffi 库?
- java - 需要使用 OpenCsv 或任何其他实用程序将 Java 中的嵌套 bean 转换为 csv