JAVA 为啥要重写equals 方法才能对一个值进行操作(容器)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 为啥要重写equals 方法才能对一个值进行操作(容器)相关的知识,希望对你有一定的参考价值。
import java.util.*;
public class BasicContainer
public static void main(String[] args)
Collection c = new HashSet();
c.add("hello");
c.add(new Name("f1","l1"));
c.add(new Integer(100));
c.remove("hello");
c.remove(new Integer(100));
System.out.println
(c.remove(new Name("f1","l1"))); //如果我下面没重写Object的equals方法为什么不能修改Name的值??
System.out.println(c);
class Name /*implements Comparable*/
private String firstName,lastName;
public Name(String firstName, String lastName)
this.firstName = firstName;
this.lastName = lastName;
public String getFirstName()
return firstName;
public String getLastName()
return lastName;
public String toString()
return firstName + " " + lastName;
public boolean equals(Object obj)
if (obj instanceof Name)
Name name = (Name) obj;
return (firstName.equals(name.firstName))
&& (lastName.equals(name.lastName));
return super.equals(obj);
public int hashCode()
return firstName.hashCode();
所以你必须重写equals方法根据对象的属性值来判断两个对象是否相等。追问
public boolean equals(Object obj)
这里传进来的是哪个Name ?
c.add(new Name("f1","l1")); 这个 ? 还是
System.out.println
(c.remove(new Name("f1","l1"))); 这个 ?
基础不是很好
所以object的equal方法只有被重写之后才能比较这两个对象的“内容”是不是相同,而不是比较是不是同一个对象。显而易见,楼主的这段程序不重写Object方法比较的两者是不是同一个Name对象 当然就不能remove成功了。所以就有当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
我初学容器的时候也有同样的疑惑,建议楼主多查API文档,加油,祝你成功!追问
public boolean equals(Object obj)
这里传进来的是哪个Name ?
c.add(new Name("f1","l1")); 这个 ? 还是
System.out.println
(c.remove(new Name("f1","l1"))); 这个 ?
基础不是很好
当然是调用remove方法时的了,因为你要移除c.add(new Name("f1","l1")) 这个生成的Name。所以你要调用equal比较再生成一个Name比较两个内容是否相同:c.remove(new Name("f1","l1"))); (这里的new Name是新生成的)
参考技术B 你说的什么意思??什么叫你能修改name值?建议你去看看object的equals方法:public boolean equals(Object obj),所有类都默认继承object类,也就是name类继承了object的equals方法,此equals方法内部不可能知道name类的firstName、lastName属性,更不可能去判断firstName、lastName属性是否正确了。追问public boolean equals(Object obj)
这里传进来的是哪个Name ?
c.add(new Name("f1","l1")); 这个 ? 还是
System.out.println
(c.remove(new Name("f1","l1"))); 这个 ?
基础不是很好
后面那个,在打印对象时默认调用equals方法
java 基础笔记--hashCode(),你好,为啥要重写
从学习java开始就知道,hashCode()方法是object类本身就有的方法,所有的类都继承了object,也就了hashCode()这个方法。
在学java的时候,就被告知在重写equals方法时,也要重写hashCode方法。当时没细想,以为这个是语法规定。
后来了解到,这个确实java规定:
hashcode相等的两个对象内容不一定相等。
对象内容相等的两个对象hashcode一定相等!
如果比较两个对象是否相等。比较两个对象的内容涉及的东西比较多,但是hashcode只是一个int数字,要比较还是不简单!性能上比equals快多了。在set,map等集合类中,代码中都是先利用hashcode判断key是否存在和重复。这也就是如果自定义类作为key时,要求要重写hashCode方法。
默认的hashcode的值是对象在内存中的地址。
随便提一下,String也是重写了hashCode方法的。
String类关键代码如下:
/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
就是它了,根据内容来决定hashcode的值的。
测试代码如下:
public class Dog {
private int age;
private String name;
public Dog(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Hash {
public static void main(String[] args) {
// TODO Auto-generated method stub
String a="abc";
String b=new String("abc");
String c=new String("abc");
String d="abc";
System.out.println(" a hashcode:"+a.hashCode()+"--"+(a==d));
System.out.println(" b hashcode:"+b.hashCode()+"--"+(b==c));
System.out.println("c hashcode:"+c.hashCode());
System.out.println("d hashcode:" +d.hashCode());
Dog dog1=new Dog("aa", 1);
Dog dog2=new Dog("aa", 1);
System.out.println(dog1.hashCode());
System.out.println(dog2.hashCode());
}
}
运行结果(每次运行dog的hashcode的结果不一样。下图仅仅是参考):
至于equals的方法介绍参考:
https://www.cnblogs.com/yxnchinahlj/archive/2010/09/27/1836556.html
以上是关于JAVA 为啥要重写equals 方法才能对一个值进行操作(容器)的主要内容,如果未能解决你的问题,请参考以下文章
【彻底理解】 为啥重写equals()方法为啥要重写hashCode()方法
java中重写Object类的equals方法为啥要重写hashcode方法?不重写可以吗?
java中重写Object类的equals方法为啥要重写hashcode方法?不重写可以吗?