欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HashSet add方法存储自定义类型对象常用方法

程序员文章站 2022-05-13 23:50:59
...

Set集合存储自定义类型对象

Set集合存储自定义类型对象案例:

public class Test2 {

	public static void main(String[] args) {
		HashSet<Student1> set = new HashSet<>();
		Student1 stu = new Student1("1");
		set.add(stu);
		set.add(new Student1("1"));	
		System.out.println(set.size());
	}
}
class Student1{
	String id;
	public Student1(String id) {
		this.id = id;
	}	
}

执行结果为:2
上述代码中两个学生对象id都为1,显然在现实生活中id相等的学生应该是同一个学生,那应该如何实现id相等的对象只存一次呢?
add的执行过程为:HashSet中的add方法→HashMap中的put方法→HashMap中的putVal,而putVal的部分代码为:

 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

putVal方法的详细分析请点击HashSet集合中add()的执行过程详解
我们可以看到在 if ((p = tab[i = (n - 1) & hash]) == null)和 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))语句中用到了hash值和equals方法,在jdk中找到hash值的计算和equals方法如下:

	static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    public boolean equals(Object obj) {
        return (this == obj);
    }

如果想要某种特定属性相同的对象只在Set集合中添加一次,那么就需要重写hashCode()和equals()方法,让特定属性确定hash值,以及对比特定属性是否相等。
重写代码如下:

	public boolean equals(Object obj) {
		if(obj instanceof Student1) {//判断obj是否为Student1对象
			Student1 student = (Student1)obj;//上转型对象进行下转换
			return id.equals(student.id);//重写equals方法,实质为return this.id.equals(student.id);也就是return key.id.equals(k.id);
		}
		return false;
	}
	@Override
	public int hashCode() {
		return id.hashCode();
	}

重写之后执行结果为:1
即Set集合中只有一个对象,该对象为stu,之后的new Student1(“1”)没有加入Set集合。

相关标签: HashSet