黑马程序员技术交流社区

标题: java基础笔记之HashSet [打印本页]

作者: hehaiwei    时间: 2016-3-4 12:59
标题: java基础笔记之HashSet
HashSet
HsahSet底层是哈希表数据结构,可以保证元素的唯一性,但不保证元素有序
唯一性主要依赖于两个方法:一个是hasCode方法,一个是equals方法。
如果我们想要存储元素,想让元素具有唯一性,只需要在对应的元素中重写hasCode方法和equals方法
代码演示:集合中添加字符串
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> h = new HashSet<String>();
h.add("hello");
h.add("world");
h.add("java");
h.add("world");

for(String s : h){
System.out.println(s);
}
}
}
运行结果:
hello
java
world
解释:上面中我添加了同样的字符串,”world“,但是打印的时候只有一个,说明其唯一性,但是为什么唯一。
查看原码可知:在String类中,有equals方法和hashCode方法,在添加的时候就会进行比较,看元素是否相同,是就不添加,不是才添加。下面来看一下原码:
h.add("hello") ;
h.add("world") ;
h.add("java") ;
h.add("world") ;

public interface Collection {....}
public interface Set extends Collection {...}
public class HashSet implements Set {
private static final Object PRESENT = new Object();//成员类
public boolean add(E e) {//e="hello"
        return map.put(e, PRESENT)==null;
    }
//add方法可以看出,其本质是返回map的put方法。
//map就是HashSet的构造方法中的new HashMap<>(),如下所示,在我们new HashSet()的时候就已经创建//了,创建了一个HashMap的对象,将地址值赋给map,这样map就指向了HashMap,代表了HashMap
public HashSet() {
        map = new HashMap<>();//返回一个hashmap对象
    }

public class HashMap {
//这是HashMap的put方法,首先传递了两个参数key和vaule,hello就key的值
public V put(K key, V value) {// key="hello",vaule是PERSON 也就上面的成员类
// 这一步是判读哈希表是否存在 , 如果不存在就创建一个哈希表
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null) // key="hello",所以这一步不走
            return putForNullKey(value);           
        int hash = hash(key); //将key的值传递给hash方法, 通过hashCode方法计算一个int类型的值
      
        int i = indexFor(hash, table.length);       // 在哈希表中查找是否存在该hash值
        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; //如果是同一元素,就返回oldVaule,就是该元素没有被添加进去
            }
        }
        modCount++;
        addEntry(hash, key, value, i); // 把元素添加到集合中
        return null;
    }   
//这是hash方法,用来获取hashCode值
final int hash(Object k) {// key="hello"
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
        h ^= k.hashCode();// key="hello"
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);//最终影响返回结果的就是h ^= k.hashCode();这一步,这是计算哈希值
    }
}
private transient HashMap<E,Object> map;//hashmap集合

}

    transient int hashSeed = 0;

作者: 天赐潇潇    时间: 2016-3-4 13:08
好,收藏了,研究一下




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2