HashSet

HashSet实现于Set接口,使用HashMap作为数据支撑,它不会保证遍历的顺序,允许null元素

注意方法不是同步的,如果有多线程进行操作需要进行同步处理。也可以使用

Set s = Collections.synchronizedSet(new HashSet(...))

来创建一个线程安全的Set。

创建HashSet

// HashSet的数据真正的储存在HashMap中
private transient HashMap<E,Object> map;
// HashSet中存储的所有value值同一个静态变量值
private static final Object PRESENT = new Object();

如果你还不了解HashMap的原理,请查看HashMap

public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
}

仅仅是初始化了HashMap。

添加值

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

通过HashMap的内部原理可知,其put方法会在新添加元素至HashMap时;或者如果新添加的值产生了hash冲突,并且在Node链中找不到与key对应的值时才会返回null。所以我们得知在这两种情况下,HashSet才算把元素添加成功!

删除值

public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
}

通过HashMap的内部原理可知,当待删除的对象被成功删除后会返回一个非null的Node。而我们存储的是同一个PRESENT对象,所以可以使用等于符号判断是否是删除成功。

iterator遍历

public Iterator<E> iterator() {
        return map.keySet().iterator();
}

通过HashMap的内部原理可知,HashSet此时可以创建一个可以遍历的Iterator对象。该对象遍历HashMap的key值,而HashSet中的值就是存储在HashMap中的key中,因此此时可以获取到HashSet中的值。

性能问题

由于HashSet中使用HashMap存储,所以其性能受制于HashMap,请查看其实现原理。

results matching ""

    No results matching ""