java - TreeMap更低/更高的getter

时间:2015-06-18 08:58:18

标签: java reverse treemap

也许我的逻辑停止了一段时间,但我发现这种行为令人困惑。假设我有一个如下的TreeMap:

  TreeMap<Integer, Double> map = new TreeMap<Integer, Double>(Collections.reverseOrder());
    map.put(123, 0.5);
    map.put(678, 1.0);
    map.put(567, 0.1);

    int key = 100;

现在,我想使用map.lowerEntry(key)并根据getter的文档:

  

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

我希望结果null,但系统调用System.out.println("Lower than "+key+ " is "+map.lowerEntry(key));会产生Lower than 100 is 123=0.5。如果我使用记录为

map.higherEntry(key)
  

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

然后我得到了想要的结果,但根据文档它是反直觉的。我想在TreeMap上调用Collections.reverseOrder()比较器会反转地图中应用的逻辑吗?

修改 使用TreeSet在使用Collections.reverseOrder()比较器初始化时,我得到一致的行为(关于函数名称):

TreeSet<Integer> set = new TreeSet<Integer>(Collections.reverseOrder());
    set.add(123);
    set.add(678);
    set.add(567);

int key = 200;
System.out.println("Lower than "+key+ " is "+set.tailSet(key));

产生我期望的Lower than 200 is [123]。 TreeMap和TreeSet之间的这种不一致是否正常?请有人请解释一下吗?谢谢。

2 个答案:

答案 0 :(得分:1)

我会尝试和#34;总结&#34;以上对某些结构的评论:

TreeMap.lowerEntry(key)TreeSet.headSet(key)具有基本相同的行为,即它们返回低于键的元素。同样适用于TreeMap.higherEntry(key)TreeSet.tailSet(key)

在它们中的任何一个上使用反向比较器将导致顺序反转,即越高越低越低。当键/元素是数字等时,这似乎是违反直觉的,但这样会颠倒它们的排序顺序。

如果向元素添加一些语义,可能更容易理解:

让我们说我们正在处理一个计算错误发生的票务系统,而某些人则定义了要修复错误的优先级。

现在您想要遍历该错误列表并显示它们,因此您使用TreeMap<Integer, ErrorDescription>对它们进行排序。

根据键的语义,您可以使用不同的比较器:

  • 如果密钥是优先级,普通概念是较低的数字意味着更高的优先级,您只需将地图从最小到最高编号,即您只需使用标准订单。
  • 如果密钥是出现的次数,那么您最有可能希望将具有最高出现次数的错误放在列表的开头,因此您将使用相反的顺序。但是,由于整数被定义为从小到高排序,因此您需要使用反转比较器。

最后,你最后评论的引用:

  

我发现这些功能的文档和/或名称具有误导性。

如果你考虑上面的例子,只是在数字上添加语义会改变&#34; lower&#34;并且&#34;更高&#34;。另外考虑到数字键只是一种键,你也可以使用日期,字符串,枚举或许多其他具有自然顺序的对象(因此实现Comparable)或需要在逐案(因此使用Comparator)。

因为文档必须适用于很多不同的情况,所以很难以适合一切的方式编写文档。 &#34;降低&#34;的含义并且&#34;更高&#34;无论如何取决于情况,因此最简单地使用该措辞并将语义的解释留给开发人员。

答案 1 :(得分:0)

你想要的答案可能就在这里:TreeMap(Comparator<? super K> comparator)构造函数

  

构造一个新的空树图,根据给定的比较器排序......

     

<强>参数:

     

comparator - 将用于订购此地图的比较器。如果为null,则将使用键的自然顺序。

然后,您应该仅针对此comparator阅读小于大于

另外,正如托马斯指出的那样,你可能会对tailSet(key)的含义感到困惑。从文档中,它应该为您提供大于或等于键的元素。因此,按相反的顺序,您会得到较低的值。