散列表(哈希表)
- 实现一个基于链表法解决冲突问题的散列表
class ChainingHashSet<K, V> {
private int num; // 当前散列表中的键值对总数
private int capacity; // 散列表的大小
private SeqSearchST<K, V>[] st; // 链表对象数组
// 构造函数
public ChainingHashSet(int initialCapacity){
capacity = initialCapacity;
st = (SeqSearchST<K, V>[]) new Object[capacity];
for(int i = 0; i < capacity; i++){
st[i] = new SeqSearchST<>();
}
}
// hash()方法
private int hash(K key){
return (key.hashCode() & 0x7fffffff) % capacity;
}
public V get(K key){
return st[hash(key)].get(key);
}
public void put(K key, V value){
st[hash(key)].put(key, value);
}
}
// SeqSearchST基于链表的符号表实现
class SeqSearchST<K, V>{
private Node first;
// 结点类
private class Node{
K key;
V value;
Node next;
// 构造函数
public Node(K key, V val, Node next){
this.key = key;
this.value = val;
this.next = next;
}
}
// get()方法
public V get(K key) {
for(Node node = first; node != null; node = node.next){
if(key.equals(node.key)){
return node.value;
}
}
return null;
}
// put()方法
public void put(K key, V value) {
// 先查找表中是否已经存在相应的key
Node node;
for(node = first; node != null; node = node.next){
if(key.equals(key)){
node.value = value; // 如果key存在,就把当前value插入node.next中
return;
}
}
// 表中不存在相应的key,直接插入表头
first = new Node(key, value, first);
}
}
实现一个 LRU 缓存淘汰算法
public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
private final int maxCapacity;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
private final Lock lock = new ReentrantLock();
public LRULinkedHashMap(int maxCapacity) {
super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
this.maxCapacity = maxCapacity;
}
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
return size() > maxCapacity;
}
@Override
public boolean containsKey(Object key) {
try {
lock.lock();
return super.containsKey(key);
} finally {
lock.unlock();
}
}
@Override
public V get(Object key) {
try {
lock.lock();
return super.get(key);
} finally {
lock.unlock();
}
}
@Override
public V put(K key, V value) {
try {
lock.lock();
return super.put(key, value);
} finally {
lock.unlock();
}
}
public int size() {
try {
lock.lock();
return super.size();
} finally {
lock.unlock();
}
}
public void clear() {
try {
lock.lock();
super.clear();
} finally {
lock.unlock();
}
}
public Collection<Map.Entry<K, V>> getAll() {
try {
lock.lock();
return new ArrayList<Map.Entry<K, V>>(super.entrySet());
} finally {
lock.unlock();
}
}
}