Java中LinkedHashMap和TreeMap的equals()和hashCode()方法有什么区别?

3
equals()和hashCode()方法的覆盖在TreeMap中不是必须的,但在HashMap和LinkedHashMap中则是必须的。
TreeMap使用ComparableComparator接口提供的实现来对使用自定义类作为MapKey进行操作。

这个说法正确吗?


你的第二个声明是错误的。TreeMap 也应该遵守 Map 的一般契约,并在此基础上应用 Comparable 和 Comparator。 - Suresh Atta
但是在尝试调试程序代码时......它从未进入equals()方法......也尝试实现碰撞条件...每次返回相同的int值...但没有一个情况达到了equals()。 - user3571396
4个回答

1

TreeMap 内部仅使用 compare 函数来处理键。

containsValue 方法内部使用 equals。因此,需要重新定义值的 equals,而不是键的。

HashMapLinkedHashMap 在键上内部使用 equalshashCode。因此,您需要为您的键类重新定义它们。对于 TreeMap、HashMapLinkedHashMap 也使用 equals 来处理值。因此,需要重新定义值的 equals。


1
为了回答这样的问题,最好阅读文档而不是进行测试。测试并没有什么作用。即使您看到某些方法没有被调用,也不意味着它们在以后的Java版本或使用另一个JDK供应商时不会被调用。或者可能在执行地图的其他操作时调用这些方法。
在这种特定情况下,文档中如下所述:
请注意,像任何排序映射一样,树映射维护的顺序(无论是否提供显式比较器)必须与equals保持一致,如果这个排序映射要正确实现Map接口。(有关与equals一致的精确定义,请参见ComparableComparator。)这是因为Map接口是根据equals操作定义的,但是排序映射使用其compareTo(或compare)方法执行所有键比较,因此在这种方法被视为相等的两个键在排序映射的角度来看是相等的。即使排序映射的排序与equals不一致,它的行为也是明确定义的;它只是没有遵守Map接口的一般约定。

强调我的。

根据最后一句话,如果您没有为键定义equals方法,则TreeMap将是完全功能的,但这将违反Map接口的契约。例如,{{link1:Map.containsKey}} 契约如下:

如果此映射包含指定键的映射,则返回true。更正式地说,仅当此映射包含键k的映射(使得(key==null ? k==null : key.equals(k)))时,才返回true

因此,如果您使用具有不一致equals实现的键的TreeMap,则会出现错误。如果您将映射传递给某些假定传递的映射遵循合同的方法,则该方法可能无法正常工作。

1
我总是遵循一个简单的配方:对于所有的映射实现,我总是重写hashCode()equals()。如果这个映射也是一个SortedMap,那么我还会重写compare()或者实现一个Comparator(在这两种情况下,比较必须与equals()一致,这意味着比较的结果必须在实际相等的元素之间返回0)。
这个配方使我能够使用我觉得最适合解决特定问题的任何映射实现,甚至允许我为同一个键类使用不同的映射实现。

0

是的,我是正确的(如果我错了,请纠正我)...请检查以下代码 -

In this following code `equals()` and `hashCode()` is never get called , so in `TreeMap` does these never gets called in `TreeMap` ?? Or something wrong I have Done ???? its never printing `inside hashCode()` `inside equals()`

package Map;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class HashCodeEqualsTester {

    public static void main (String[] args){

        Car car1 = new Car("788");
        Driver driver1 = new Driver("Kevin");

        Car car2 = new Car("656");
        Driver driver2 = new Driver("Bob");

        Car car3 = new Car("343");
        Driver driver3 = new Driver("Stuart");

        Map<Car, Driver> myMap = new TreeMap<Car, Driver>();
        // Map<Car, Driver> myMap = new LinkedHashMap<Car, Driver>();
        // Map<Car, Driver> myMap = new HashMap<Car, Driver>(); 
        // try to run these 3 one at a time and see how does it behave 

        myMap.put(car1, driver1);
        myMap.put(car2, driver2);
        myMap.put(car3, driver3);



        System.out.println(myMap);
    }
}

class Car implements Comparable{
    private String carNumber;

    public Car (String carNumber){
        this.carNumber = carNumber;
    }
    public String getCarNumber() {
        return carNumber;
    }
    public void setCarNumber(String carNumber) {
        this.carNumber = carNumber;
    }
    public String toString(){
        return ("Car Number : " + carNumber);
    }

    public int hashCode(){
        System.out.println("Inside hashCode()");
        int hashCode = 1;
        hashCode = hashCode * this.getCarNumber().hashCode();
        System.out.println("For Car Number : " + this.getCarNumber() + " hashcode is : " + hashCode);
        //return hashCode;
        return 1000;
    }

    public boolean equals(Object o){
        System.out.println("Inside equals()");
        if (!(o instanceof Car)) {
            return false;
        } else {
            Car car = (Car) o;
            return (this.getCarNumber().equalsIgnoreCase(car.getCarNumber()));
        }
    }

    public int compareTo(Object o) {
        Car car = (Car) o;

        return (this.getCarNumber().compareTo(car.getCarNumber()));
    }
}

class Driver {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString(){
        return (this.getName() + " ");
    }
    public Driver(String name){
        this.name = name;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接