去重原理简介:

HashSet是Java集合框架中的一种数据结构,用于存储不重复的元素。它基于哈希表(Hash Table)实现,并使用哈希函数将元素映射到哈希表中的位置。

HashSet的去重原理是利用哈希表的特性来判断元素是否已经存在。当我们向HashSet中添加一个元素时,它会首先计算该元素的哈希码(通过调用元素对象的hashCode()方法),然后根据哈希码找到对应的哈希表中的位置。

如果该位置上没有其他元素,就直接将该元素插入到该位置,并标记为已占用。如果该位置上已经有其他元素存在,那么就需要比较新元素和已存在元素是否相等(通过调用元素对象的equals()方法)。如果相等,说明元素已经存在于HashSet中,不做任何操作;如果不相等,就发生了哈希冲突,需要采取解决冲突的方法,例如使用链表或者树结构来处理冲突。

通过这种方式,HashSet可以保证其中的元素不重复,因为在添加元素时会进行哈希码的比较和相等性判断。当我们需要判断一个元素是否已经存在于HashSet中时,它会根据元素的哈希码快速定位到可能的位置,然后再进行相等性比较,从而实现高效的去重操作。

详细解析:

HashSet加入的对象需要重写hashCode方法和equals方法,因为对于自定义类需要提供判断怎样才算重复元素的方法。

HashSet的特点
1.元素不能重复且无序

2.允许有null值

3.线程不安全

4.底层的数据结构是HashMap

Hashset的实现原理
1.在HashSet中,元素被存放在HashMap的key中,value则是一个常量对象,所以HashSet能够保证元素的不重复。

2.当我们向HashSet中添加元素时,HashSet会调用该元素的HashCode()方法计算出该元素的哈希值,然后根据哈希值计算出该元素在数组中存放的位置,如果该位置没有元素,就直接将该元素存放在当前位置,如果该位置有元素,就会调用equals()方法来对俩个元素比较,如果比较值是true,HashSet会认为这俩个元素一样,就不会对其进行存储,如果比较值是false,HashSet会认为这俩个元素不一样,就会用开放寻址法在数组中查找可以存放该元素的空位置进行存储。

hashCode()与equals()的相关规定
1.如果两个对象相等,则hashcode一定也是相同的
2.两个对象相等,对两个equals方法返回true
3.两个对象有相同的hashcode值,它们也不一定是相等的
4.综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
5.hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

代码解析

此时没有重写hashcode()和equals()方法

package Test;

public class User {
	 private String name;

	public User(String name) {
		this.name = name;
	}
}
package Test;

import java.util.HashSet;
import java.util.Set;

public class Demo02 {
	public static void main(String[] args) {
		User u1 =new User("关羽");
		User u2 =new User("关羽");
		Set<User> ser =new HashSet<User>();
		ser.add(u1);
		ser.add(u2);
        System.out.println(ser);	
	}
}

java用hashset对对象list去重 java中hashset去重_散列表

俩个user对象都是关羽,但是没有重写HashCode()和equals()方法,所以HashCode()值不一样,所以 HashSet认为添加进去的俩个user对象是不同的

我们重写了HashCode()和equals()方法之后再进行测试

package Test;

public class User {
	 private String name;

	public User(String name) {
		this.name = name;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "name=" + name;
	}
package Test;

import java.util.HashSet;
import java.util.Set;

public class Demo02 {
	public static void main(String[] args) {
		User u1 =new User("关羽");
		User u2 =new User("关羽");
		Set<User> ser =new HashSet<User>();
		ser.add(u1);
		ser.add(u2);
        System.out.println(ser);	
	}
}

java用hashset对对象list去重 java中hashset去重_散列表_02

可以看出当我们重写了HashCode()和equals()方法之后HashSet会认为我们添加的俩个user对象是同一个user对象;