-
学习借鉴:https://blog.csdn.net/winy_lm/article/details/50946488
-
需求:在嵌套获取分类节点子节点的时候,需要对获取的字节点进行去重,所以采用了Set集合,也就是没有重复数据的特性
-
具体解决思路
在Set中如果存储类型是基本类型,也就是系统已经封装好的类型,那么就不需要重写hashCode和equals这两个方法,但是如果是我们自己定义的Bean类型,就需要对如何判断重复进行自定义。
我在里面看到了很重要的一点:先判断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;
}
}
- 复杂对象解决思路
/**
* 类描述:set集合针对String 类型和8大基础数据类型 过滤掉重复数据,
* 如果存放的是其他类型对象,则需要重写hashCode方法和equals方法,
* 当hashcode相等时(先执行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不能相同。这样才能判断去重,可以继续添加