1.Set集合如何过滤重复元素
Set集合底层的实现是基于HashMap实现的,判断元素是否重复的过程也是通过HashMap的key去重原理来实现的。具体实现原理如下:
将元素加入Set集合时,会调用元素的hashCode()方法生成一个哈希码,并将元素作为key存储到HashMap中。当加入重复元素时,HashMap会根据元素的哈希码查找是否已经存在同样的key,如果存在则会进行值的覆盖,不会发生集合的变化;如果不存在,则将元素添加到Set集合中。
2.为什么重写hashCode()时,必须重写equals()?
在Java中,hashCode()和equals()是用于实现set集合中对象的唯一性和相等性比较的两个方法。
hashCode()方法返回对象的hash code值,用于在哈希表中查找对象。Java集合框架中的HashSet、HashMap、Hashtable等都是基于哈希表实现的。当我们向集合中添加元素时,集合会先调用元素的hashCode()方法,然后根据返回的hash code值将元素存储到相应的位置上。如果两个对象的hashCode()方法返回值不同,则集合认为这两个对象不相等,即使这两个对象的属性相同,equals()方法也返回false。
而equals()方法用于比较两个对象是否相等。在Java中,如果两个对象相等,那么它们的hashCode()方法返回值必须相等,否则在HashSet、HashMap、Hashtable等基于哈希表实现的集合中,这两个对象会被当作不同的对象处理。
因此,当我们重写一个类的hashCode()方法时,必须同时重写equals()方法,以保证两个对象相等当且仅当它们的属性相同,而不是仅仅因为它们的hashCode()方法返回相同的值。
3.为什么会产生哈希冲突
哈希冲突是指两个或更多的关键字被哈希函数映射到了同一个哈希桶(或哈希表)的问题。产生哈希冲突的原因有很多,主要包括以下几点:
-
哈希函数设计不合理。哈希函数是将关键字映射到哈希桶的过程,如果哈希函数设计不合理,会导致哈希值的分布不均匀,进而导致哈希冲突的产生。
-
哈希表的容量过小。当哈希表容量不足以存储所有可能的关键字时,就会出现哈希冲突。
-
数据的分布不均匀。如果待哈希的数据分布不均匀,例如数据的小数位数比较少,或数据内容比较集中,就容易产生哈希冲突。
-
多线程并发操作。当多个线程同时操作哈希表时,如果没有对并发写操作进行合理的同步处理,就容易产生哈希冲突。
哈希冲突会导致哈希表的查询、插入、删除等操作变得低效,需要采用一些解决冲突的方法,例如链式哈希、开放地址哈希等。
简单来说就是hashCode()方法的返回值是int类型,它有最大值,而计算的哈希值是无限的。在一个有限的空间里面存储无限的值,就会出现重复的哈希值。例如:
class Main {
public static void main(String[] args){
String s1 = new String("通话");// 创建一个字符串对象s1,其值为"通话"
String s2 = new String("重地");// 创建一个字符串对象s2,其值为"重地"
System.out.println(s1.hashCode());//s1的哈希值
System.out.println(s2.hashCode());//s2的哈希值
}
}
输出结果为:
1179395
1179395
在这个例子中,s1 和 s2 这两个字符串对象的内容分别为 "通话" 和 "重地",虽然它们的值不同,但是它们的哈希值是相等的。这是因为在生成字符串的哈希值时,使用的是字符串的内容来生成哈希值,而不是字符串的对象引用值。因此,只要两个字符串对象的内容相同,它们的哈希值就会相等。