集合(一)Set:HashSet,TreeSet
参考:https://mp.weixin.qq.com/s/ZTNJIbrDfLUdkEU5aiDRFQ
Set是不允许出现重复的集合,主要有HashSet和TreeSet两大类,判断重复元素时,会用到HashCode()和equals()方法。
HashSet使用HashMap的key存储元素,计算元素的hash值来获取元素在集合中的位置,
TreeSet是红黑树结构,每一个元素都是树中的节点,插入的元素都是进行排序。
1.HashSet
HashSet基于HashMap,底层是通过HashMap的API来实现的。是哈希表结构。
1)允许null值
2)无序
3)非线程安全
key是新增的元素,value是一个固定的值。
它继承于AbstractSet,实现了Set, Cloneable, Serializable接口。
HashSet中的两个变量:
map:存储元素的地方,是一个HashMap,当有元素要插入到HashSet中,会被当成map的key保存到map属性中去
present:每个key对应的vaule默认为PRESENT,也就是new了一个对象
hashSet的构造方法:初始化map属性,new了一个HashMap对象
add()添加方法,底层调用hashmap的put()方法
源码:
如果了解了HashMap的实现原理,那下面的代码很容易理解,先计算hash值,如果相同,则调用equals(), == 进行判断,若相同则覆盖原来的元素,不相同的时候才向map中添加元素。
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
2.TreeSet
底层通过TreeMap来实现,具有排序功能(自然排序(默认)和自定义排序)
它继承AbstractSet,实现NavigableSet(搜索功能), Cloneable(克隆), Serializable(序列化,可用hessian协议来传输)接口。
1)有序
2)允许null值
3)底层红黑树结构
4)元素不允许重复
5)非线程安全
TreeSet的add()方法:底层调用TreeMap的put()方法,put()方法里面会调用到compare(key ,key)方法,进行key大小的比较。因此TreeSet的类型如果是自定义的类型,就必须重写compareTo()方法或者实现Comparator接口重写compare()方法,说明比较的是类中的哪个属性才行,不然会报错