分销网站建立,个人备案网站营业执照,网站如何做监控直播,小程序开发多少钱HashSet 是一个基于 HashMap 实现的无序列表。 它不保证数据存储的顺序, 但是可以保证存储的数据是唯一不重复的, 同时支持存储 null。
如果再了解 HashMap 后, HashSet 是几个 Collection 实现中最容易理解的集合, 因为 HashSet 的所有操作都是借助于 HashMap 实现的。
Hash…HashSet 是一个基于 HashMap 实现的无序列表。 它不保证数据存储的顺序, 但是可以保证存储的数据是唯一不重复的, 同时支持存储 null。
如果再了解 HashMap 后, HashSet 是几个 Collection 实现中最容易理解的集合, 因为 HashSet 的所有操作都是借助于 HashMap 实现的。
HashSet 内部声明了一个 HashMap, 然后将数据存储在 HashMap 的 key 中, 所有的 value 直接设置为同一个 Object 对象, 借助 HashMap key 的唯一性间接的实现了 HashSet 的唯一性。
1 HashSet 中的几个重要属性
public class HashSetE {// 一个静态, 不可变的 Object 变量// 静态保证了唯一性, 整个应用就一个, 可以节省空间// 不可变, 进一步保正这个对象不会被任何线程修改private static final Object PRESENT new Object();// HashSet 中存储数据的地方// 就是借助 HashMap 存储的, 存入 HashSet 的数据, 统一放到这个 HashMap 的 key 中, 这个 key 对应的 value 则统一为上面定义的静态 Objectprivate transient HashMapE,Object map;
}2 HashSet 的构造方法
2.1 无参的构造函数
public HashSet() {// 为属性 map 赋值, 声明为 HashMapmap new HashMap();
}很简单, 创建一个 HashMap, 并赋值给自己存储数据的属性 HashMapE,Object map
2.2 指定容量的构造函数
public HashSet(int initialCapacity) {// 指定容量 map new HashMap(initialCapacity);
}同样, 直接创建一个指定容量的 HashMap, 然后赋值给自己存储数据的属性 HashMapE,Object map
2.3 指定容量和负载因子的构造函数
public HashSet(int initialCapacity, float loadFactor) {// 指定容量, 负载因子map new HashMap(initialCapacity, loadFactor);
}依旧是直接调用对应 HashMap 的方法, 创建出需要的 HashMap, 再赋值给自己的 HashMapE,Object map 属性
2.4 给定一个 Collection 的构造函数
public HashSet(Collection? extends E c) {// 创建一个 HashMap 赋值到自己的属性map new HashMap(Math.max((int) (c.size()/.75f) 1, 16));// 添加全部addAll(c);
}// 将一个集合中的数据遍历添加到自己的 HashMap 中
public boolean addAll(Collection? extends E c) {boolean modified false;// 依次遍历每一个元素for (E e : c)if (add(e))modified true;return modified;
}// 向自己的 HashMap 添加数据
public boolean add(E e) {// 很简单的调用 HashMap 的 put 方法, key 值为需要存入的数据, value 为 声明好的静态变量 PRESENTreturn map.put(e, PRESENT)null;
}2.5 一个比较特殊的构造函数: 没有提供出去的构造函数
HashSet(int initialCapacity, float loadFactor, boolean dummy) {// dump 参数没有作用, 只是为了重载// 通过这个构造函数, 可以将 HashSet 默认的 map 实现变为 LinkedHashMap, 主要是给子类 LinkedHashSet 起使用, 达到有序的效果map new LinkedHashMap(initialCapacity, loadFactor);
}3 HashSet 的操作方法
3.1 添加数据
public class HashSetE {// 单个添加元素public boolean add(E e) {// 直接调用 map 的 put 方法return map.put(e, PRESENT)null;}
}3.2 其他的添加方法
public class HashSetE {// 直接添加一个集合public boolean addAll(Collection? extends E c) {boolean modified false;for (E e : c)// 遍历所有的元素, 调用自身的 add 方法if (add(e))modified true;return modified;}
}3.3 删除数据
public class HashSetE {public boolean remove(Object o) {// 同样是调用 map 的 remove 方法return map.remove(o)PRESENT;}
}同样的可以通过 removeAll 直接清空 HashSet 的数据
3.4 查询数据
Set 比较特殊, 没有提供直接获取值的方法 get 方法。 因为没必要, 如果你现在已经有一个数据 a, Set.get(a), 返回结果想要什么? 如果只是单纯的是想判断对象是否存在可以通过 contain 方法进行判断。
4 HashSet 的补充 因为 HashSet 是通过 HashMap 实现的, HashMap 的 key 可以存 null, 但是只能存一个, 所以 HashSet 支持存 null, 同时只能存一个因为 HashMap 是非线程安全的所以 HashSet 也是线程非安全的。HashSet 也是自定义了序列化方法HashSet 内部没有提供自己的迭代器, 他内部是通过 HashMap 的 key 迭代器实现的HashMap 支持 fail-fast 机制, 理所当然的 HashSet 也是。HashSet 的数据是无序的, 如果需要使用有序的 Set, 可以使用 LinkedHashSet, 内部是借助 LinkedHashMap 实现