Java Set集合通过重写hashCode和equals实现去重

Posted wx5cb71f4b705da

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Set集合通过重写hashCode和equals实现去重相关的知识,希望对你有一定的参考价值。


  • 需求:在嵌套获取分类节点子节点的时候,需要对获取的字节点进行去重,所以采用了Set集合,也就是没有重复数据的特性
  • 具体解决思路
    在Set中如果存储类型是基本类型,也就是系统已经封装好的类型,那么就不需要重写hashCode和equals这两个方法,但是如果是我们自己定义的Bean类型,就需要对如何判断重复进行自定义。
  • ​Set去重流程​

我在里面看到了很重要的一点:先判断hashCode是否相同再判断equals是否相同

for (Entry<K,V> e = table[i]; e != null; e = e.next) //每添加一个,则循环判断是否与map中的元素相等
Object k;
// 先判断hashcode是否一致,然后再判断值是否相等
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;

  • 复杂对象解决思路
(先执行hashCode方法),则会去执行equals方法,比较每个属性的值
* 如果一致的话,则不会存进set,否则加入set集合
*
public class MmallCategory implements Serializable
private Integer id;
private Integer parentId;
private static final long serialVersionUID = 1L;
public Integer getId()
return id;

public void setId(Integer id)
this.id = id;

@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MmallCategory category = (MmallCategory) o;
//只是比较id,只有属性值一致才会返回true
return id != null ? id.equals(category.id) : category.id == null;


/**
* 重写hashCode方法,返回的hashCode不一样才会再去比较每一个属性的值
* @return
*/
@Override
public int hashCode()
//return id.hashCode
return id != null ? id.hashCode() : 0;

总结:根据实现类和Set流程的关键代码我就明白了。

根据Set流程博客的链接,HashSet的add方法其实依赖于HashMap的put方法

public boolean add(E e) 
return map.put(e, PRESENT)==null;

然后我们继续看HashMap put方法的具体实现

public V put(K key, V value) 
if (key == null)
return putForNullKey(value);
//获取hashCode
int hash = hash(key.hashCode());
//这个应该似乎是找出对应index索引
int i = indexFor(hash, table.length);
//每添加一个,则循环判断是否与map中的元素相等
for (Entry<K,V> e = table[i]; e != null; e = e.next)
Object k;
// 先判断hashcode是否一致,然后再判断值是否相等
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;


//遍历完不重复
modCount++;
addEntry(hash, key, value, i);
return null;

简单点说就是对Set中的元素循环遍历,判断条件是hashCode和equals不能重复,或者hashCode相同时,equals不能相同。这样才能判断去重,可以继续添加


以上是关于Java Set集合通过重写hashCode和equals实现去重的主要内容,如果未能解决你的问题,请参考以下文章

阿里巴巴Java开发手册-集合处理

阿里巴巴Java 开发手册编程规约之集合处理

阿里巴巴Java开发手册-集合处理规约

为啥在java的set集合中 hashcode相同 但equals结果可能为false

java里equals和hashCode之间啥关系

为啥要重写toString方法和hashcode方法