Set(保证唯一)
无序,唯一(不可重复)
public HashSet() {
map = new HashMap<E,Object>();
}
public V put(K key, V value) {
//判断对象是否为Null
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
//比较hash值、地址值和内容
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;
}
为啥存储字符串的时候,字符串内容相同的只存储一个。 --就是hashCode()和equals()方法
通过查看add方法的源码,我们知道这个方法的底层依赖两个方法 hashCode()和equals()
步骤:
先看hashCode()值是否相同
相同:继续走equals()方法
返回true:说明元素重复,不添加
返回false:说明元素不重复,则添加到集合中去
不同:就直接把元素添加到集合中去
如果类没有重写这两个方法,默认使用Object()。一般来说不相同。因为之比较地址值
而String类重写了hashCode()和equals()方法,所以他就可以把相同的字符串去掉,之保留其中一个
LinnkedHashSet集合
底层数据结构是hash表和链表
哈希表保证元素唯一
链表保证元素有序。(存储和取出顺序一致)
TreeSet集合
排序、唯一
A:底层数据结构是红黑树(是一个自平衡的二叉树)
B:保证元素的排序和唯一(运用二叉排序树)
a:自然排序:(元素具备比较性)
让元素所属的类实现Comparable接口
b:比较器排序(集合具备比较性)
让集合的构造方法接受comparator的实现类对象
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
// TBD:
// 5045147: (coll) Adding null to an empty TreeSet should
// throw NullPointerException
//
// compare(key, key); // type check
root = new Entry<K,V>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<K,V>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}