java - TreeMap lower/higher 吸气剂
java - TreeMap lower/higher getters
也许我的逻辑停止了一点,但我发现这种行为令人困惑。假设我有一个 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 的文档:
Returns a key-value mapping associated with the greatest key strictly less than the given key, or null if there is no such key.
我希望结果为 null
,但系统调用 System.out.println("Lower than "+key+ " is "+map.lowerEntry(key));
产生 Lower than 100 is 123=0.5
。如果我使用记录为
的 map.higherEntry(key)
Returns a key-value mapping associated with the least key strictly greater than the given key, or null if there is no such key.
然后我得到了想要的结果,但根据文档,这是违反直觉的。我想在 TreeMap 上调用 Collections.reverseOrder()
比较器会反转地图内部应用的逻辑?
编辑
当使用 Collections.reverseOrder()
比较器初始化时,使用 TreeSet 我得到一致的行为(关于函数名称):
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 之间的这种不一致是否正常?有人可以解释一下吗?谢谢你。
或许你想要的答案在这里:TreeMap(Comparator<? super K> comparator)
构造函数
Constructs a new, empty tree map, ordered according to the given comparator ...
Parameters:
comparator
- the comparator that will be used to order this map. If null, the natural ordering of the keys will be used.
那么,你应该只阅读小于和大于的comparator
。
此外,正如 Thomas 所指出的,您可能对 tailSet(key)
的含义感到困惑。从文档中,它应该为您提供 大于或等于 键的元素。因此,以相反的顺序,您会得到较低的值。
我会尝试 "summarize" 上面针对某些结构的评论:
TreeMap.lowerEntry(key)
和 TreeSet.headSet(key)
具有基本相同的行为,即它们 return 低于键的元素。 TreeMap.higherEntry(key)
和 TreeSet.tailSet(key)
.
也是如此
在其中任何一个上使用反向比较器都会导致顺序颠倒,即高变低,低变高。当 keys/elements 是数字等时,这似乎有悖常理,但这样会颠倒它们的排序顺序。
如果给元素添加一些语义,可能会更容易理解:
假设我们正在处理一个票务系统,该系统计算错误的发生次数,同时有人定义错误修复的优先级。
现在您想遍历该错误列表并显示它们,因此您使用 TreeMap<Integer, ErrorDescription>
对它们进行排序。
根据密钥的语义,您将使用不同的比较器:
- 如果关键是优先级,一般概念是数字越小优先级越高,您只需将地图从小到大排序,即您只需使用标准顺序即可。
- 如果关键是出现次数,您很可能希望出现次数最多的错误位于列表的开头,因此您将使用相反的顺序。但是,由于整数被定义为从小到大排序,因此您需要使用反向比较器。
最后,引自您上一条评论:
I find the documentation and/or names of the functions misleading.
如果您考虑上面的示例,仅向数字添加语义就会改变 "lower" 和 "higher" 的含义。另外考虑到数字键只是一种类型的键,您还可以使用日期、字符串、枚举或许多其他具有自然顺序(因此实现 Comparable
)或需要按顺序排列的对象逐案分析(因此使用 Comparator
)。
因为文档必须适用于许多不同的情况,所以很难以适合所有情况的方式编写它。 "lower" 和 "higher" 的含义取决于具体情况,因此最简单的方法是只使用该措辞并将语义的解释留给开发人员。
也许我的逻辑停止了一点,但我发现这种行为令人困惑。假设我有一个 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 的文档:
Returns a key-value mapping associated with the greatest key strictly less than the given key, or null if there is no such key.
我希望结果为 null
,但系统调用 System.out.println("Lower than "+key+ " is "+map.lowerEntry(key));
产生 Lower than 100 is 123=0.5
。如果我使用记录为
map.higherEntry(key)
Returns a key-value mapping associated with the least key strictly greater than the given key, or null if there is no such key.
然后我得到了想要的结果,但根据文档,这是违反直觉的。我想在 TreeMap 上调用 Collections.reverseOrder()
比较器会反转地图内部应用的逻辑?
编辑
当使用 Collections.reverseOrder()
比较器初始化时,使用 TreeSet 我得到一致的行为(关于函数名称):
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 之间的这种不一致是否正常?有人可以解释一下吗?谢谢你。
或许你想要的答案在这里:TreeMap(Comparator<? super K> comparator)
构造函数
Constructs a new, empty tree map, ordered according to the given comparator ...
Parameters:
comparator
- the comparator that will be used to order this map. If null, the natural ordering of the keys will be used.
那么,你应该只阅读小于和大于的comparator
。
此外,正如 Thomas 所指出的,您可能对 tailSet(key)
的含义感到困惑。从文档中,它应该为您提供 大于或等于 键的元素。因此,以相反的顺序,您会得到较低的值。
我会尝试 "summarize" 上面针对某些结构的评论:
TreeMap.lowerEntry(key)
和 TreeSet.headSet(key)
具有基本相同的行为,即它们 return 低于键的元素。 TreeMap.higherEntry(key)
和 TreeSet.tailSet(key)
.
在其中任何一个上使用反向比较器都会导致顺序颠倒,即高变低,低变高。当 keys/elements 是数字等时,这似乎有悖常理,但这样会颠倒它们的排序顺序。
如果给元素添加一些语义,可能会更容易理解:
假设我们正在处理一个票务系统,该系统计算错误的发生次数,同时有人定义错误修复的优先级。
现在您想遍历该错误列表并显示它们,因此您使用 TreeMap<Integer, ErrorDescription>
对它们进行排序。
根据密钥的语义,您将使用不同的比较器:
- 如果关键是优先级,一般概念是数字越小优先级越高,您只需将地图从小到大排序,即您只需使用标准顺序即可。
- 如果关键是出现次数,您很可能希望出现次数最多的错误位于列表的开头,因此您将使用相反的顺序。但是,由于整数被定义为从小到大排序,因此您需要使用反向比较器。
最后,引自您上一条评论:
I find the documentation and/or names of the functions misleading.
如果您考虑上面的示例,仅向数字添加语义就会改变 "lower" 和 "higher" 的含义。另外考虑到数字键只是一种类型的键,您还可以使用日期、字符串、枚举或许多其他具有自然顺序(因此实现 Comparable
)或需要按顺序排列的对象逐案分析(因此使用 Comparator
)。
因为文档必须适用于许多不同的情况,所以很难以适合所有情况的方式编写它。 "lower" 和 "higher" 的含义取决于具体情况,因此最简单的方法是只使用该措辞并将语义的解释留给开发人员。