20170507@Set接口

来源:互联网 发布:萨尔 知乎 编辑:程序博客网 时间:2024/06/05 19:32

Set接口,它里面的集合,所存储的元素就是不重复的
Set集合取出元素的方式(Set没有索引):
1.迭代器
2.增强for

Set的功能和Collection是一样的,不做更多赘述了。

Set接口的实现类:HashSet(哈希表)
特点:
1.无序集合,存储和取出的顺序不同。
2.没有索引。
3.不存储重复元素。

代码的编写上,和ArrayList是一样的,不同的是不可以做索引的相关操作。

HashSet集合的特点:
底层数据结构:哈希表。
存储,取出速度比较快,且线程不安全。

HashSet集合的API介绍:此类实现Set接口,由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同。
HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。

HashSet是如何保证集合元素的唯一性的?
保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。
当向哈希表中存放元素时,需要根据Object类中的hashCode方法。在像哈希表中存放对象时,会调用对象的hashCode方法,计算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,称为哈希冲突。这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

如果我们往集合中存放自定义的对象,想要保证其唯一性,就必须复写hashCode和equals方法建立属于当前对象的比较方式。(Eclipse中可以直接生成)。

API中关于重写HashCode和equals的协定:

hashCode 的常规协定是:

在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。

如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。

如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:

自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。

对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。

传递性:对于任何非空引用值 x、y 和z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。

一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。

对于任何非空引用值 x,x.equals(null) 都应返回 false。

Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

Set接口的另一个实现类: LinkedHashSet

它是链表和哈希表组合的一个数据存储结构。可以保证数据保证有序。

常见问题:
如果两个对象哈希值相同,equals一定返回true吗?
不一定。

如果两个对象equals方法返回true,哈希值一定相同吗?
一定。

原创粉丝点击