java集合中的set接口,HashSet集合,哈希链表的特性,hashCode和equals()方法的作用和深入理解,哈希表一些问题。两道面试题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33322074/article/details/86522165

一、set接口和List接口中的区别

注意:set接口中的方法和Collection接口中的方法一模一样。

二、Set接口的实现类

1、HashSet集合 ,本质是HashMap<>

2、set接口使用

无序例子:

注意:输出时没有按输入时的顺序输出。

3、增强for的形式

不允许存储元素,如果有重复元素不会报错,但是只会输出一个。

三、哈希表的特性

1、其实应该说是哈希链表,首先有一个数组,每个数组元素下是一个链表。这个数组初始时有个容量,当存储元素达到一定量时就会产生哈希表的再哈希(rehash)其中这个一定量就是加载因子。rehash就是重新开辟一个数组,并将之前数组中的内容全部复制进去。相当的耗费时间。

2、哈希表

这张图解释了哈希表的存储过程:首先,哈希表先调用对象的哈希值,通过哈希值来判断哈希表中是否有该对象存在。但是即使哈希值一样也不会放弃存储。因为也许元素不一样但是哈希值确相同,于是接着比较看元素的值是否相同,即:调用对象的equals()方法,如果equals()方法一样,那么就表明该元素真的重复了。

总结一下:先判断对象的哈希值是否相同,若返回true,再调用equals()方法判断对象的值是否相同。如果返回true表示重复,不会存储到哈希表上。

注意:String类重写了父类的HashCode方法,重写的结果就是:new String("abc") 不管new几次只要字符相同,HashCode都相同。

此外Object的HashCode方法是不可见的。没有开源。如图所示:

四、哈希表面临的问题

上图是new String(),由于String类重写了HashCode方法,导致实例化HashCode值相同。如果对象是自定义类。当存储相同的值时会出现HashCode的值就会不同。就会打印出相同的值。那么如何避免打印相同的值呢?如图:

如上图:由于是自定义对象,导致能存储看着相同的值,其实是匿名对象,他们的hashcode固然不同,所以被存进去了。对于用户来说如何将这些相同的值当做一个对象呢?

那就需要重写hashCode方法。

首先:设置无重复值的过程有两步,一是通过比较hashCode,如果hashCode相同就比较equals()方法。如果也相同就表明存储的内容重复。

其中第一步是:让相同的对象得到相同的哈希值。equals()方法是比较不同对象却又有相同哈希值的情况。通过这两个方法实现了相同数据看成一个对象。为了减少让不同对象却具有相同哈希值的概率。可以通过如下重写hashCode()方法。

对于equals()方法也需要重写。

注意:eclipse可以自动创建hashCode和equals()方法。

五、LinkedHashSet 基于链表的哈希表实现

同样不会存储相同的数据。

注意:八种基本类型都重写了hashCode和equals()方法。

六、两道面试题

但是:如果这样

将静态变量a+1,hashCode每次都会不同。其实sun公司对这个定了一个协议:

1、hashCode相同对象返回值每次必须相等。故返回值不能搞成a+1。

2、equals()方法为true时,hashCode必须相同。

3、equals()方法不为true时,hashCode不一定相同。

猜你喜欢

转载自blog.csdn.net/qq_33322074/article/details/86522165