Java LinkedHashMap和树映射中的equals()和hashCode()?
Java LinkedHashMap和树映射中的equals()和hashCode()?,java,collections,treemap,linkedhashmap,Java,Collections,Treemap,Linkedhashmap,TreeMap不需要重写equals()和hashCode(),而HashMap和LinkedHashMap需要重写 TreeMap在使用用户创建的类作为Map的Key时,使用Comparable或Comparator接口提供的实现 这是否正确?内部TreeMap仅对键使用比较功能 方法包含值内部使用等于。因此,有必要为值而不是键重新定义等于 HashMap和LinkedHashMap在键上内部使用equals和hashCode。因此,您需要为密钥类重新定义它。至于TreeMap,HashMap
TreeMap
不需要重写equals()和hashCode()
,而HashMap
和LinkedHashMap
需要重写
TreeMap
在使用用户创建的类作为Map的Key
时,使用Comparable
或Comparator
接口提供的实现
这是否正确?内部TreeMap
仅对键使用比较功能
方法包含值
内部使用等于
。因此,有必要为值而不是键重新定义等于
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;
}
}
在下面的代码中,`equals()`和`hashCode()`永远不会被调用,所以在`TreeMap`中,`TreeMap`是否永远不会调用它们??或者是我做错了什么????它从不打印'inside hashCode()'`inside equals()`
包装图;
导入java.util.HashMap;
导入java.util.Map;
导入java.util.TreeMap;
公共类HashCodeEqualsTester{
公共静态void main(字符串[]args){
Car car1=新车(“788”);
驾驶员1=新驾驶员(“凯文”);
Car car2=新车(“656”);
驾驶员2=新驾驶员(“Bob”);
Car car3=新车(“343”);
驾驶员3=新驾驶员(“斯图尔特”);
Map myMap=newtreemap();
//Map myMap=新建LinkedHashMap();
//Map myMap=newhashmap();
//试着一次运行这3个,看看它是如何运行的
myMap.put(car1,driver1);
myMap.put(car2,driver2);
myMap.put(car3,driver3);
System.out.println(myMap);
}
}
一类汽车{
私有字符串卡号;
公共汽车(字串卡号){
this.carNumber=carNumber;
}
公共字符串getCarNumber(){
返回卡号;
}
公共无效设置卡号(字符串卡号){
this.carNumber=carNumber;
}
公共字符串toString(){
返回(“车号:”+卡号);
}
公共int hashCode(){
System.out.println(“内部hashCode()”;
int hashCode=1;
hashCode=hashCode*this.getCarNumber().hashCode();
System.out.println(“对于车号:“+this.getCarNumber()+”哈希代码为:“+hashcode”);
//返回哈希码;
返回1000;
}
公共布尔等于(对象o){
System.out.println(“内部等于()”;
如果(!(车辆实例)){
返回false;
}否则{
汽车=(汽车)o;
return(this.getCarNumber().equalsIgnoreCase(car.getCarNumber());
}
}
公共整数比较对象(对象o){
汽车=(汽车)o;
返回(this.getCarNumber().compareTo(car.getCarNumber());
}
}
类驱动程序{
私有字符串名称;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串toString(){
返回(this.getName()+“”);
}
公共驱动程序(字符串名称){
this.name=名称;
}
}
要回答这些问题,最好阅读文档而不是进行测试。测试没有显示任何结果。即使您看到方法没有被调用,也不意味着在以后的Java版本中或使用其他JDK供应商时不会调用它们。或者,在对地图执行其他操作时,可能会调用这些方法
在这种特殊情况下,报告中说:
请注意,树映射维护的顺序与任何排序映射一样,无论是否提供显式比较器,必须与equals
一致,如果此排序映射要正确实现映射
接口。(请参见Comparable
或Comparator
以获取与相等的一致性的精确定义)之所以如此,是因为Map
接口是根据equals
操作定义的,但排序后的映射使用其compareTo
(或compare
)方法执行所有关键比较,因此,从排序映射的角度来看,用这种方法认为相等的两个键是相等的。已排序映射的行为定义良好,即使其顺序与equals
不一致;它只是没有遵守Map
接口的总合同
我的
因此,根据最后一句话,TreeMap
如果不为键定义equals
方法,将完全起作用,但这将违反Map
接口的约定。例如,合同如下:
如果此映射包含指定键的映射,则返回true
。更正式地说,返回true
当且仅当此映射包含键k
的映射,从而(键==null?k==null:key.equals(k))
因此,如果使用TreeMap
的键具有不一致的equals
实现,这将是错误的。如果将映射传递给某个方法,而该方法假定传递的映射遵循约定,则该方法可能无法正常工作。我始终遵循一个简单的方法:对于所有映射实现,我始终覆盖hashCode()
和equals()
。如果映射也是一个SortedMap
,我也会覆盖compare()
或实现一个比较器
(在这两种情况下,比较必须与<