Collection子接口Set
存储元素特点:无序,不可重复,特点:
1、元素没有下标的概念
2、元素不能重复(调用元素的equal方法判断元素是否重复,同意元素的地址,两个相同内容的对象)既然元素不能重复,那要怎么做才能快速的判断即将要存入的元素是否在集合中已经存在了呢?
最直接的方法就是直接判断,但要是元素多了,效率就很慢,所以要将集合中的元素分组,之后
再有元素存入时,和组的特征进行比对,看在哪个组中,之后再进行逐一比对,确定是否重复,
详细内容分如下:
java中为每个元素提供了一个hash算法,调用hashCode方法,返回一个int类型的数值存入并检查的详细过程:
set集合存入第一个元素:
先计算第一个元素的hashCode方法的返回值。
返回一个int类型值,会放入相应的一个hash值区间内
第二个元素
先计算元素的hashCode的返回值
返回一个已有的int值,并去查找对应区间位置上有没有元素。先进行hashCode的比较,之后会调用equal方法,对元素的内容进行比较,如果返回true,那就不会存入,反之就会存入
如果返回一个全新的int值,则直接存入集合
3、可以添加null元素,但只能添加一次
应用 :
首先重写equal方法,在重写hashCode方法关于equal
Object类中默认的实现方式是:return this == obj,就是说,只有this和obj引用同意对象时,才会返回true。
而我们往往需要用equal来判断2个对象是否等价,而非验证他们的唯一性。
按照约定,equals要满足以下规定
自反性:x.equals(x) 一定是true
对null:x.equals(null) 一定是false
对称性:x.equals(y)和y.equal(x)结果一致
传递性:a和b可以 equals,b和c可以 equals,那么a和c也一定可以equals
一致性:x.equals(y)不管调用几次结果都一致
关于hashCode
Object类的hashCode的方法:返回对象的散列值,这个值根据对象的内存地址经过hash算法处理最后返回一个int值
关于重写hashCode,要遵守的约定:
重写equal方法,则必须重写hashCode()方法
若两个对象equals返回true,则hashCode()有必要返回相同的int值
若两个对象equals返回false,则hashCode()不一定返回不同的int值(但生成不同的int值,可提高哈希表的性能)
还可以总结出:
若两个对象hashCode()返回相同int值,则equals不一定返回true
若两个对象hashCode()返回不同int值,则equals一定返回false
同一对象在执行期间若已经存在集合中了,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题
(也就是说,存入集合后的值不能进行修改,否则会出现问题)