首页 > 解决方案 > 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)

有什么我做错了吗?数据集以一种非常奇怪的方式格式化,所以我将其排除在外,但很明显,从权重列表计算总数不是我面临的问题。

标签: javaarraysdictionarynullpointerexceptionnull

解决方案


javadoc说:

返回与严格大于给定键的最小键关联的键值映射,如果没有这样的键,则返回 null。

您的代码可以:

double value = rng.nextDouble() * total;

长话短说:唯一的解释是没有符合该标准的价值。换句话说:你的逻辑在这里从根本上被打破了。

关键是:您正在乘以一个随机值。所有的赌注都在这里了。有时您的代码可能会导致非空结果,有时不会。


推荐阅读