重寫equals() and hashCode()
對於TreeMap
不是必需的,同時需要HashMap
和LinkedHashMap
。Java中的equals()和hashCode()LinkedHashMap和樹形圖?
TreeMap
工程實施上使用用戶創建的類作爲Key
時Map
這是正確的Comparable
或Comparator
interface
提供?
重寫equals() and hashCode()
對於TreeMap
不是必需的,同時需要HashMap
和LinkedHashMap
。Java中的equals()和hashCode()LinkedHashMap和樹形圖?
TreeMap
工程實施上使用用戶創建的類作爲Key
時Map
這是正確的Comparable
或Comparator
interface
提供?
內部TreeMap
只能使用compare
函數的鍵。
方法containsValue
內部使用equals
。所以有必要重新定義equals
的值,而不是鍵。
HashMap
和LinkedHashMap
在鍵上內部使用equals
和hashCode
。所以你需要爲你的關鍵類重新定義它。至於TreeMap,HashMap
和LinkedHashMap
使用equals
作爲值。所以有必要重新定義值的等於。
是的,我是正確的(請糾正我,如果我錯了)...查看下面的代碼 -
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;
}
}
要回答這樣的問題,它更更好的閱讀文檔,而不是進行測試。測試沒有顯示。即使您看到這些方法未被調用,但這並不意味着它們不會在更多的Java版本或另一個JDK供應商中被調用。或者可能在您的地圖上執行其他一些操作時可能會調用這些方法。
在這種特殊情況下,documentation說以下內容:
注意,排序由一棵樹映射維護,像任何排序的映射,無論是否提供了明確的比較,必須一致
equals
如果這個排序圖是要正確實現Map
接口。 (對於一致的精確定義與equals
參見Comparable
或Comparator
)。這是因爲該Map
接口在equals
操作定義的,而是一個排序映射使用它compareTo
(或compare
)方法所有的鍵比較,於是兩個從排序映射的角度來看,這種方法認爲相同的密鑰是相等的。即使其排序與equals
不一致,排序映射的行爲也是;它只是不服從Map
接口的總體合同。
強調我的。
因此,根據最後一句話,如果您沒有定義密鑰的equals
方法,TreeMap
將完全正常工作,但它會違反Map
接口的合同。例如,Map.containsKey
合同如下:
返回
true
如果此映射包含指定鍵的映射。更正式地,返回true
當且僅當該映射包含關鍵字k
的映射,例如(key==null ? k==null : key.equals(k))
。
因此,如果您使用TreeMap
鍵與equals
實現不一致,這將是錯誤的。如果您將地圖傳遞給某種假定傳遞的地圖符合合同的方法,則該方法可能會錯誤地工作。
我總是遵循一個簡單的配方:對於所有的地圖實現,我總是覆蓋hashCode()
和equals()
。如果地圖也是SortedMap
,我也覆蓋compare()
或執行Comparator
(在兩種情況下,比較必須與equals()
一致,這意味着如果比較的元素實際上相等,則比較結果必須返回0
)。
這個配方允許我使用任何地圖實現,我覺得最適合我正在處理的特定問題,它甚至允許我爲同一個關鍵類使用不同的地圖實現。
你是對的 – Eran
你的第二個陳述是錯誤的。 'TreeMap'也應該服從Map的一般合約,然後在它之上,Comparable和Comparator來。 –
但是當試圖調試程序代碼....它永遠不會進入equals()方法....試圖實現碰撞條件以及..通過每次返回相同的int值...沒有它的情況下達到等於()。 – user3571396