【问题标题】:TreeMap.higherEntry returns an unexpected nullTreeMap.higherEntry 返回意外的 null
【发布时间】:2018-11-12 08:50:10
【问题描述】:

好的,所以我有这段代码应该从加权列表中获取随机条目。但是,当我尝试调用 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)

我做错了什么吗?数据集的格式非常奇怪,所以我将其省略,但很明显,从权重列表计算总数不是我面临的问题。

【问题讨论】:

  • it returns null even though there is a higher entry available?你确定有更高的入口吗?您可以在调用map.higherKey(value) 之前简单地打印mapvalue 并亲自查看。
  • 考虑到输出没有一个值似乎大于 5。所以地图不包含任何高于 9 的键。
  • 似乎没有更高的条目。查看您正在打印的值:System.out.println(total); - 这是根据total += ((Weighted) e).getWeight(); 添加的值的总和如果您查看打印端的总数,添加的最高值应该是 5.0
  • 您将总计打印到控制台,而不是您添加的值。正如您在累积总值中看到的那样,没有添加高于 9.987466924354226 的值。最高值为 5.0。
  • @Eran 现在我觉得自己像个大白痴。睡了四个小时后,最简单的事情有点错过了你的雷达。

标签: java arrays dictionary nullpointerexception null


【解决方案1】:

javadoc 说:

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

您的代码可以:

double value = rng.nextDouble() * total;

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 这不是“关闭”线程的正确方法。您接受回答了您的问题的答案。如果其中一个答案激发了您的更改...然后对其发表评论,并让编写答案的人更新该输入,然后接受该答案。
    【解决方案3】:

    这不是错误

    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

    【讨论】:

    • 我不明白你的最后两行,11 和 9 是什么?
    【解决方案4】:

    地图的键应该是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。我希望这足以解释它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-26
      • 2014-07-26
      • 1970-01-01
      • 2013-11-25
      相关资源
      最近更新 更多