问题描述:
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet
类:
void add(key)
向哈希集合中插入值key
。bool contains(key)
返回哈希集合中是否存在这个值key
。void remove(key)
将给定值key
从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。-
示例:
输入: ["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"] [[], [1], [2], [1], [3], [2], [2], [2], [2]] 输出: [null, null, null, true, false, null, true, null, false] 解释: MyHashSet myHashSet = new MyHashSet(); myHashSet.add(1); // set = [1] myHashSet.add(2); // set = [1, 2] myHashSet.contains(1); // 返回 True myHashSet.contains(3); // 返回 False ,(未找到) myHashSet.add(2); // set = [1, 2] myHashSet.contains(2); // 返回 True myHashSet.remove(2); // set = [1] myHashSet.contains(2); // 返回 False ,(已移除)
题解:
package basement.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* @author: hj
* @className: MyHashSet
* @Describe:TODO
*/
public class MyHashSet implements HashSetDemo{
/*
* 题解1:HashSet是基于HashMap的一个没有重复元素的集合,允许存在null值
* HashMap是散列表方式生成 769 = 512 + 256 + 1
* */
private static final int CAPACITY = 769;
private LinkedList<Integer>[] list;
public MyHashSet(){
list = new LinkedList[CAPACITY];
for (int i = 0; i < CAPACITY; i++){
list[i] = new LinkedList<Integer>();
}
}
public int hash(Object key){
int h ;
// 高八位
return key == null ? 0 : ((h = key.hashCode()) ^ (h >>> 8))% CAPACITY;
}
@Override
public void add(int key) {
int hashCode = hash(key);
Iterator<Integer> iterator = list[hashCode].iterator();
while (iterator.hasNext()){
Integer ele = iterator.next();
if (ele.equals(key)){
return;
}
}
list[hashCode].offerLast(key);
}
@Override
public void remove(int key) {
int hashCode = hash(key);
Iterator<Integer> iterator = list[hashCode].iterator();
while (iterator.hasNext()){
Integer ele = iterator.next();
if (ele.equals(key)){
list[hashCode].remove(ele);
return;
}
}
}
@Override
public boolean contains(int key) {
int hashCode = hash(key);
Iterator<Integer> iterator = list[hashCode].iterator();
while (iterator.hasNext()){
Integer ele = iterator.next();
if (ele.equals(key)){
return true;
}
}
return false;
}
}
链表capacity设计参考源码,感谢大佬的讲解源码hashcode()取值的博文,获益匪浅:https://blog.youkuaiyun.com/weixin_46195957/article/details/125274802https://blog.youkuaiyun.com/weixin_46195957/article/details/125274802
HashSet与HashMap重学
HashMap
hashmap是一个散列表,存储内容是键值对(key-value)映射。hashmap的key与value的类型可以相同也可以不同,不受限制。
HashMap中键值对可以重复,取值就近原则,允许存在null数值hashMap.put("key4",null);
基础操作(增删改查)
-
定义
HashMap<String, Integer> hashMap = new HashMap<>();
-
增加
hashMap.put("key1", 1); hashMap.put("key2", 2); hashMap.put("key3", 3);
-
查
Object val = hashMap.get("key1");
-
删
hashMap.remove("key1"); Object val2 = hashMap.get("key1"); System.out.println(val2); //null hashMap.clear(); //全清除
-
替换
hashMap.replace("key2", 3);
-
键值对数量
hashMap.size();
-
包含
hashMap.containsKey("key3")
-
是否为空
hashMap.isEmpty()
-
返回所有values的数组集合
System.out.println(hashMap.values());
HashSet
HashSet是基于HashMap的一个不允许有重复元素的集合,但允许有null数值
set是不包含重复元素的集合,即不包含e1.equals(e2)
-
定义:
Set<Integer> hashSet = new HashSet<>();
-
增加:
hashSet.add(1);
迭代增加:
List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); HashSet<Integer> intSet = new HashSet<>(); Iterator in = list.iterator(); while (in.hasNext()){ intSet.add((Integer) in.next()); } // 或 for(int i : list){ inset.add(li); } // 注意迭代器位置 Iterator out = intSet.iterator(); while (out.hasNext()){ System.out.println(out.next()); } System.out.println(intSet.size());
Set<Integer> hashSet = new HashSet<>(); System.out.println(hashSet.size()); Iterator<Integer> iterator = hashMap.values().iterator(); while (iterator.hasNext()){ hashSet.add(iterator.next()); } Iterator<Integer> it = hashSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } System.out.println(hashSet.size());
Set<Integer> hashSet = new HashSet<>(); System.out.println(hashSet.size()); Iterator<Integer> iterator = hashMap.values().iterator(); while (iterator.hasNext()){ hashSet.add(iterator.next()); } Iterator<Integer> it = hashSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } System.out.println(hashSet.size());
-
判断元素是否存在
System.out.println(hashSet.contains(3));
-
删除
hashSet.remove(3); System.out.println(hashSet.contains(3)); hashMap.clear(); System.out.println(hashSet.size());
HashSet去重方式
通过equals()与hashCode()实现去重
hashCode()通过比较不同HashSet对象的HashCode值进行判断是否对等
实现哈希集合
HashSet寄予HashMap实现数据存储,HashMap是散列表,故可依据散列表实现方式实现。