LinkedList和TreeMap:compareTo等于还是等于?

时间:2019-01-29 09:46:35

标签: java linked-list treemap

我需要澄清有关TreeMap和LinkedList的使用。这两个结构是否使用compareTo或equals?

尤其是,TreeMap保持键的顺序,我想使用为键定义的类的compareTo方法。但是,在使用get时,他们是否使用compareTo或equals来查看是否包含您传递的密钥?

我对LinkedList中的contains和getIndex也有同样的疑问。

2 个答案:

答案 0 :(得分:1)

TreeMapLinkedList的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,如果compareToequals不符(即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