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集合。
上一篇: layui 点击放大图片
下一篇: java set HashSet