TreeMap.higherEntry返回意外的null

时间:2018-11-12 08:50:11

标签: java arrays dictionary nullpointerexception 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)

我在做错什么吗?数据集的格式非常奇怪,因此我不予赘述,但显然,从权重列表计算总数并不是我要面对的问题。

4 个答案:

答案 0 :(得分:1)

javadoc说:

  

返回与至少大于给定键的最小键关联的键-值映射关系;如果没有这样的键,则返回null。

您的代码可以:

double value = rng.nextDouble() * total;

长话短说:唯一的解释是,没有满足该标准的价值。换句话说:您的逻辑从根本上被打破了。

重点是:您要乘以 random 值。所有赌注都在这里。有时您的代码可能会导致非空结果,有时却不会。

答案 1 :(得分:0)

回答我自己的问题以关闭此线程。我的问题在这里:

map.put(((Weighted) e).getWeight(),e);
total += ((Weighted) e).getWeight();

该地图应该是每个键都比前一个更大的地图,但是由于睡眠不足,我只是将原始权重添加到了地图中。这是固定的一段代码:

total += ((Weighted) e).getWeight();
map.put(total,e);

答案 2 :(得分:0)

这不是错误

public static void main(String[] args) {
  // creating tree map 
  TreeMap<Integer, String> treemap = new TreeMap<Integer, String>();

  // populating tree map
  treemap.put(2, "two");
  treemap.put(1, "one");
  treemap.put(3, "three");
  treemap.put(6, "six");
  treemap.put(5, "five");

  // getting higher key for key 4          
  System.out.println("Checking values of the map");
  System.out.println("Value is: "+ treemap.higherKey(3));
}     

此输出为5

您的代码正在执行此操作:

11-> getHigherKey = 5

9-> getHigherKey = null

答案 3 :(得分:0)

地图的键应该是total的值,而不是各个权重。

    double total = 0;
    for (E e : this) {
        if (e instanceof Weighted) {
            total += ((Weighted) e).getWeight();
        } else {
            total += defaultWeight;
        }
        map.put(total, e);
        System.out.println(total);
    }
    double value = rng.nextDouble() * total;
    double result = map.higherKey(value);
    System.out.println(value + ", " + result);
    return result.getValue();

例如,如果您有分别具有权重4、2、5的条目A,B,C,则要具有键4、6、11。这样,A覆盖0-4,B覆盖5-6,C覆盖7-11。我希望能对此做充分的解释。