我需要澄清有关TreeMap和LinkedList的使用。这两个结构是否使用compareTo或equals?
尤其是,TreeMap保持键的顺序,我想使用为键定义的类的compareTo方法。但是,在使用get时,他们是否使用compareTo或equals来查看是否包含您传递的密钥?
我对LinkedList中的contains和getIndex也有同样的疑问。
答案 0 :(得分:1)
TreeMap
和LinkedList
的Javadoc回答:
V java.util.TreeMap.get(对象键)
返回指定键所映射到的值;如果此映射不包含键的映射关系,则返回null。
更正式地说,如果此地图包含从键k到值v的映射,使得键根据地图的顺序比较等于k ,则此方法返回v;否则返回null。 (最多可以有一个这样的映射。)
和
布尔型java.util.LinkedList.contains(对象o)
如果此列表包含指定的元素,则返回true。更正式地讲,仅当此列表包含至少一个元素(e == null?e == null:o.equals(e))时,才返回true。
因此,对于TreeMap
,使用Comparator \ Comparable实现来确定键的相等性,而对于LinkedList
,则使用equals
。
答案 1 :(得分:1)
TreeMap
使用compareTo
,如果compareTo
与equals
不符(即a.compareTo(b) == 0 <=> a.equals(b)
应该与{{1}是的)。
请注意,如果此排序后的映射是为了正确实现Map接口,则树映射...保持的顺序必须等于。
LinkedList
使用equals
。
TreeMap
必须使用与equals
一致的顺序的原因是,Map
的合同以equals
的形式定义了行为。例如,the documentation定义为:
仅当此映射包含键
时)返回true
的映射(例如k
(key==null ? k==null : key.equals(k))
假设您定义这样的类:
class Bad implements Comparable<Bad> {
@Override public int compareTo(Bad other) { return 0; }
}
如果您要写:
Bad b1 = new Bad();
Bad b2 = new Bad();
然后:
Map<Bad, String> hm = new HashMap<>();
hm.put(b1, "");
System.out.println(hm.containsKey(b2)); // false
而
Map<Bad, String> tm = new TreeMap<>();
tm.put(b1, "");
System.out.println(tm.containsKey(b2)); // true
尽管事实
System.out.println(tm.keySet().stream().anyMatch(k -> k.equals(b2))); // false
因此,TreeMap
违反了Map
的约定,因为Bad
并未与Comparable
一致地实现equals
。