3. Set
Set注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复,不会有多个元素引用相同的对象。
对象的相等性本质是对象hashCode值(java是依据对象的内存地址计算出的此序号)判断的,如果想要让两个不同的对象视为相等,就必须覆盖Object的hashCode方法和equals方法。
1. HashSet(Hash表)
哈希表存放的时哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同)而是按照哈希值来存的,所以取数据也是按照哈希值取的。元素的哈希值是通过元素hashCode方法来获取的。
HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法,如果equals结果为true,HashSet就视为同一个元素,如果equals结果为false就不是同一个元素。
哈希值相同equals为false的元素是怎么存储的,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。如图一表示hashCode值不相同的情况;图2表示hashCode值相同,但equals不相同的情况。
HashSet通过hashCode值来确定元素在内存中的位置,一个hashCode位置上可以存放多个元素。
HashSet底层原理
HashSet基于HashMap实现,放入HashSet中的元素实际上由HashMap中的key来保存,而HashMap的value则存储了一个静态的Object对象
点击查看代码
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map; //基于HashMap实现
//...
}
2. TreeSet(二叉树)
1)TreeSet是使用二叉树的原理对新add()的对象按照指定顺序(升序、降序),每增加一个对象都会进行排序,将对象插入二叉树指定的位置。
2)Integer和String对象都可以进行默认的TreeSet排序,而自定义类的对象是不可以的,自定义的类必须实现Comparable接口,并且覆写相应的compareTo()函数,才可以正常使用。
3)在覆写compare()函数时,要返回相应的值才能使TreeSet按照一定的规则来排序。
4)比较此对象与指定对象的顺序,如果该对象小于、等于、或大于指定对象,则分别返回负整数、零或正整数。
3. LinkedHashSet(HashSet+LinkedHashMap)
对于LinkedHashSet而言,它继承于HashSet,又基于LinkedHashMap来实现的。
LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承于HashSet,其所有的方法操作上又与HashSet相同,因此LinkedHashSet的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构建器,底层构造一个LinkedHashMap来实现,在相关操作上与父类HashSet的操作相同,直接调用父类HashSet的方法即可。