HashSet覆写equals 和hashcode 方法进行类别比较

一个好的类一个好的类,应该覆写equals,toString,hashcode方法,都在Object类中。我现在知道了为什么向HashSet中插入相同字符串不行,而插入相同的实例化对象可以。

Set<Person> allSet = new HashSet<Person>() ;
		allSet.add("a") ;
		allSet.add("b") ;
		allSet.add("b") ;
		allSet.add("c") ;
这里插入b 肯定是不行了,只能插进去一个。而下面这个可以插入多个:

Set<Person> allSet = new HashSet<Person>() ;
		allSet.add(new Person("张三",30)) ;
		allSet.add(new Person("李四",31)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("赵六",33)) ;
		allSet.add(new Person("孙七",33)) ;
这是因为任何类都有equals 和 hashCode方法,插入的字符串属于String类,而String类已经把equals 和hashCode 方法覆写了,使用者可以直接使用来判断插入的元素是否相等,对于用户自己定义的类而言,必须要按自己的需求进行判定覆写equals hashCode 方法。具体的覆写过程看我的另一片博客。

import java.util.Set ;
import java.util.HashSet ;
class Person{
	private String name ;
	private int age ;
	public Person(String name,int age){
		this.name = name ;
		this.age = age ;
	}
	public String toString(){
		return "姓名:" + this.name + ";年龄:" + this.age ;
	}
};
public class RepeatDemo01{
	public static void main(String args[]){
		Set<Person> allSet = new HashSet<Person>() ;
		allSet.add(new Person("张三",30)) ;
		allSet.add(new Person("李四",31)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("赵六",33)) ;
		allSet.add(new Person("孙七",33)) ;
		System.out.println(allSet) ;
	}
};
运行结果:

E:\JAVA\NotePadJava\java类集\set\TreeSet>java RepeatDemo01
[姓名:王五;年龄:32, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:李四;年龄:31, 姓名:张三;年龄:30, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]

从上面的结果中可以看出表面上好像是插入了相同的元素,HashSet对插入的元素进行存储时,每个插入的元素都有一个HashCode,根据HashCode的值来访元素,元素数值相同但背后的HashCode不同,所以可以插入,如果要去除相同的元素,要重写equals()和hashcode()方法,这两个方法在Object类中,可以查看API进行了解。

import java.util.Set ;
import java.util.HashSet ;
class Person{
	private String name ;
	private int age ;
	public Person(String name,int age){
		this.name = name ;
		this.age = age ;
	}
	public boolean equals(Object obj){	// 覆写equals,完成对象比较
		if(this==obj){
			return true ;
		}
		if(!(obj instanceof Person)){
			return false ;
		}
		Person p = (Person)obj ;	// 向下转型
		if(this.name.equals(p.name)&&this.age==p.age){
			return true ;
		}else{
			return false ;
		}
	}
	public int hashCode(){
		return this.name.hashCode() * this.age	; // 定义一个公式
	}
	public String toString(){
		return "姓名:" + this.name + ";年龄:" + this.age ;
	}
};
class RepeatDemo02{
	public static void main(String args[]){
		Set<Person> allSet = new HashSet<Person>() ;
		allSet.add(new Person("张三",30)) ;
		allSet.add(new Person("李四",31)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("王五",32)) ;
		allSet.add(new Person("赵六",33)) ;
		allSet.add(new Person("孙七",33)) ;
		System.out.println(allSet) ;
	}
};
这样可以把,相同的元素筛选出去。

一般来说,如果你要把一个类的对象放入容器中,那么通常要为其重写equals()方法,让他们比较地址值而不是内容值。特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序容器中,还要重写compareTo()方法。
equals()相等的两个对象,hashcode()一定相等;
equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
反过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。
自己找了片文章,慢慢理解。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值