浅析Set去重的原理


```java
public class Student {
	private int no;
	private String name;
	public Student() {}
	public Student(int no,String name) {
		this.no = no;
		this.name = name;
	}
	// 构造方法可以一次赋两个值,这个方法用于单个赋值
	/*public void setNo(int no) {
		this.no = no;
	}
	public void setName(String name) {
		this.name = name;
	}*/
	public int getNo() {
		return no;
	}
	public String getName() {
		return name;
	}
	public String toString() {
		return "["+no+","+name+"]";
	}
	public int hashCode() {
		return no;
	}
	// Object的equals方法不适用,所以需要重写equals()方法
	public boolean equals(Object object) {
		// 这里需要强转,因为重写时需保证与父类参数类型一致,所以重写方法的参数类型也为Object
		Student student = (Student)object;
		//this.no == no && this.name == name也可
		if(no == student.getNo() && name == student.getName()) {
			return true;
		}
		return false;
	}
}


```java
import java.util.*;
public class TestSet {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 使用顺序存储结构存储
		Set set = new HashSet();
		Student s1= new Student(1,"张三");
		Student s2 = new Student(2,"李四");
		set.add(s1);
		set.add(s2);
		set.add(new Student(3,"王五"));
		set.add(new Student(3,"王五"));
		set.add(new Student(2,"李四"));
		// 遍历方式,迭代器
		// 第一步,通过集合获取迭代器
		Iterator it = set.iterator();
		// 第二步,通过循环来控制it.next();
		while(it.hasNext()) {
			// 第三步,通过迭代器获取集合的元素it.next();
			Object object = it.next();
			System.out.println(object);
		}
		// 第二种遍历方式:foreach循环遍历
		/*for(Object o : set) {
			System.out.println(o);
		}*/
	}

}

  • 从程序的入口进来,当我向集合添加前两个元素时,如图所示,对于s1和s我是先创建的对象,然后再尝试把他们加进来,根据debug的调试过程我们可以看到,向集合添加元素时首先会去执行当前对象的hashCode()方法,返回一个hashcode值,并根据这个值,决定此元素的存放位置。第1,2两个元素hashCode值不同,所以两个元素都顺利被加进集合
  • set.add(new Student(3,“王五”));而这一行语句的执行状况是先执行Student的构造方法,再返回到当前set.add(new Student(3,“王五”));语句,再去执行Student的hashCode()方法,其他语句类似
  • 重点equals()
    我们向hashset中添加元素a,首先调用a所在类的hashcode方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在hashset底层数组中的存放(索引位置),判断此位置上是否已经有元素;

如果此位置上没有其他元素,则添加成功–情况1

如果此位置上有其它元素b(或以链表形式存在的多个元素),则比较a和b的hash值:
如果hash值不同,则元素a添加成功–情况2
通过hash值相同,进而需要调用a所在类的equals方法:
equals返回true,a添加失败
equals返回false,a添加成功

  • equals的具体执行过程:
  • 以上图代码为例,第二个元素与第五个元素相同,在执行第五个元素的添加语句时,此时第二个元素已经在集合中,返回第五个元素的hashCode值时,发现此元素的hashCode值与集合已经存在的元素相同,于是去执行第五个元素的equals方法,我重写的equals方法中if的判断条件是no == student.getNo() && name == student.getName()
    在这里插入图片描述

注意看此时的this的地址比较大,说明此时this是第五个元素,而Object地址很小,说明集合中已经存在的第二个元素才是被比较的对象,即新.equals(旧)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值