您的位置:首页 > 其它

集合框架_HashSet保证元素唯一性的源码解析

2017-01-03 22:21 417 查看
package cn.itcast_02;

import java.util.HashSet;

/*
* HashSet:存储字符串并遍历
* 问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
* 通过查看add方法的源码,我们知道这个方法底层依赖两个方法:hashCode()和equals()。
* 步骤:
* 		首先比较哈希值
* 		如果相同,继续走,比较地址值或者走equals()
* 		如果不同,就直接添加到集合中
* 按照方法的步骤来说:
* 		先看hashCode()值是否相同
* 			相同:继续走equals()方法
* 				返回true:说明元素重复,就不添加
* 				返回false:说明元素不重复,就添加到集合中
* 			不同:就值接把元素添加到集合。
* 如果类没有重写这两个方法,默认使用Object()。一般来说不会相同
* 而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
*/
public class HashSetDemo {
public static void main(String[] args) {
// 创建集合对象
HashSet<String> hs = new HashSet<String>();

// 创建并添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("android");

// 遍历集合
for (String s : hs) {
System.out.println(s);
}
}
}


interface Collection {
...
}

interface Set extends Collection {
...
}

class HashSet implements Set {
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;

public HashSet() {
map = new HashMap<>();
}

public boolean add(E e) { //e=hello,world
return map.put(e, PRESENT)==null;
}
}

class HashMap implements Map {
public V put(K key, V value) { //key=e=hello,world

//看哈希表是否为空,如果空,就开辟空间
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}

//判断对象是否为null
if (key == null)
return putForNullKey(value);

int hash = hash(key); //和对象的hashCode()方法相关

//在哈希表中查找hash值
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
//这次的e其实是第一次的world
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;
}

transient int hashSeed = 0;

final int hash(Object k) { //k=key=e=hello,
int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}

h ^= k.hashCode(); //这里调用的是对象的hashCode()方法

// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
}

hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: