java - 在 TreeMap 中键入返回 null

标签 java treemap

所以我有一个非常奇怪的错误。当我最初使用 keySet() 迭代大型 TreeMap 的前 10 个键时,我偶然发现了它。其中一个关键是返回 null,据我所知,这应该是不可能的。所以我写了下面的测试代码:

int i = 0;
        for (Map.Entry<String, Integer> es : sortedMap.entrySet()){
            if (i >= 10) {
                break;
            }

            if (sortedMap.containsKey(es.getKey())){
                System.out.println(es.getKey() + ":" + sortedMap.get(es.getKey()));
            } else {
                System.out.println("Key " + es.getKey() + " does not exist, yet...");
                System.out.println("This does work: " + es.getKey() + ":" + es.getValue());
                System.out.println("This does NOT work: " + es.getKey() + ":" + sortedMap.get(es.getKey()));
            }
            i++;
        }

并得到如下结果:

SOAP:967
'excerpt'::679
'type'::679
Key 'author_url': does not exist, yet...
This does work: 'author_url'::679
This does NOT work: 'author_url'::null
'date'::679
Android:437
TLS:295
message:283
server:230
monthly:215
<<<<<<<<<<<<<<<<<<<<DUMPING MAP!
{SOAP=967, 'excerpt':=679, 'type':=679, 'author_url':=679, 'date':=679, Android=437, TLS=295, message=283, server=230, monthly=215...

我在前十名之后切断了 map ,因为那里还有很多,但所有这些都是一个具有值(value)的关键。

所以我的问题是:为什么使用key直接从TreeMap中get(key)得到的是null,而EntrySet返回的是正确的key和value?

这是我的比较器,因为我在整数上订购:

class ValueComparator implements Comparator<Object> {

  Map<String, Integer> base;
  public ValueComparator(Map<String, Integer> base) {
      this.base = base;
  }

  public int compare(Object a, Object b) {

    if ((Integer) base.get(a) < (Integer) base.get(b)) {
      return 1;
    } else if ((Integer) base.get(a) == (Integer) base.get(b)) {
      return 0;
    } else {
      return -1;
    }
  }
}

TreeMap 构建如下:

ValueComparator bvc =  new ValueComparator(allMatches);
TreeMap<String, Integer> sortedMap = new TreeMap<String, Integer>(bvc);
//Sort the HashMap
sortedMap.putAll(allMatches);

其中 allMatches 是 HashMap<String, Integer>

最佳答案

从您的 TreeMap 显示的迭代顺序来看,您肯定使用了自定义 Comparator。 [否则迭代将按字典顺序排列]

注意根据javadocs :

The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

Finally, the implementer must ensure that compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

如果您的 Comparator 不应用这些规则 - 行为未定义,可能会显示奇怪的结果 - 如您所见。

编辑:[作为对编辑问题的回应]
您的比较器使用标识 [operator==] 来检查两个整数。
请注意,Integer 是一个对象 - 因此 operator== 只有在是同一个对象时才会返回 true
你应该使用equals()检查两个整数是否相同 - 或者更好 - 使用 Integer.compareTo()

关于java - 在 TreeMap 中键入返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9437120/

相关文章:

java - 将 ArrayList 中的相同项目分组 - MusicPlayer

java - ant junit 任务——在哪里下载 ant-junit.jar 并将它放在哪里?

Java TreeMap put vs HashMap put,自定义对象作为键

java - 以 "MMMyyyy"为键对 map 进行排序

Python & Matplotlib : multi-level treemap plot?

java - java类之间的通信

java - 在 Java 中使用 double 值时如何获得高精度答案?

java - Spring Boot 集成测试抛出错误并且无法在另一个 Maven 模块中获取现有 bean

Java比较两个csv文件

java - 将值从 HashMap 复制到 TreeMap