Java LinkedHashMap和树图中的equals()和hashCode()?

时间:2015-09-29 10:15:49

标签: java collections treemap linkedhashmap

TreeMapHashMap需要

LinkedHashMap才能覆盖TreeMap

Comparable

使用用户创建的类作为Comparator时,

interface适用于KeyMap Root | | Index.html | |____Content |____css | main.css | |____images | tips.png 提供的实施

这是对的吗?

4 个答案:

答案 0 :(得分:1)

内部TreeMap仅使用compare功能键。

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

HashMapLinkedHashMap在密钥上使用内部equalshashCode。所以你需要为你的关键班重新定义它。至于TreeMap,HashMapLinkedHashMap使用equals作为值。因此有必要重新定义值的等于。

答案 1 :(得分:1)

要回答这些问题,最好阅读文档而不是执行测试。测试没什么。即使您看到未调用方法,也不意味着它们不会在其他Java版本中调用或使用其他JDK供应商。或者在使用地图执行其他操作时,可能会调用这些方法。

在这种特殊情况下,documentation表示以下内容:

  

请注意,树形图维护的顺序,如任何有序地图,以及是否提供显式比较器,必须与 equals一致,如果此有序地图是正确实现Map接口。 (请参阅ComparableComparator以获得与equals一致的精确定义。)这是因为Map接口是根据equals操作定义的,但是有序地图使用其compareTo(或compare)方法执行所有关键比较,因此从排序地图的角度来看,这种方法认为相等的两个键是相等的。排序后的地图的行为定义良好,即使其排序与equals不一致;它只是没有遵守Map接口的一般合同。

强调我的。

因此,如果您没有为密钥定义TreeMap方法,那么根据最后一句equals将完全正常运行,但它将违反Map接口的合同。例如,Map.containsKey合同如下:

  

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

如果您使用TreeMap密钥具有不一致的equals实现,那么这将是错误的。如果您将地图传递给某个方法,该方法假定传递的地图遵循合同,则该方法可能无法正常工作。

答案 2 :(得分:1)

我总是遵循一个简单的方法:对于所有地图实现,我总是覆盖hashCode()equals()。如果地图也是SortedMap,我也会覆盖compare()或实施Comparator(在这两种情况下,比较必须与equals()一致,这意味着如果被比较的元素实际上相等,则比较必须返回0

这个方法允许我使用我认为最适合我所处理的特定问题的地图实现,它甚至允许我对同一个关键类使用不同的地图实现。

答案 3 :(得分: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;
    }
}