1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
| 一、自定义 HashMap 简易版实现(基于链地址法)
public class MyHashMap<K, V> { static class Node<K, V> { K key; V value; Node<K, V> next; Node(K k, V v) { key = k; value = v; } }
private Node<K, V>[] buckets; private int capacity = 16;
public MyHashMap() { buckets = new Node[capacity]; }
public void put(K key, V value) { int index = indexFor(key); Node<K, V> cur = buckets[index]; while (cur != null) { if (cur.key.equals(key)) { cur.value = value; return; } cur = cur.next; } Node<K, V> newNode = new Node<>(key, value); newNode.next = buckets[index]; buckets[index] = newNode; }
public V get(K key) { int index = indexFor(key); Node<K, V> cur = buckets[index]; while (cur != null) { if (cur.key.equals(key)) return cur.value; cur = cur.next; } return null; }
public void remove(K key) { int index = indexFor(key); Node<K, V> cur = buckets[index], prev = null; while (cur != null) { if (cur.key.equals(key)) { if (prev == null) { buckets[index] = cur.next; } else { prev.next = cur.next; } return; } prev = cur; cur = cur.next; } }
private int indexFor(K key) { return key.hashCode() & (capacity - 1); } }
二、LRU 缓存机制(基于 HashMap + 双向链表) import java.util.HashMap; public class LRUCache<K, V> { class Node { K key; V value; Node prev, next;
Node(K k, V v) { key = k; value = v; } }
private final int capacity; private final HashMap<K, Node> map; private Node head, tail;
public LRUCache(int capacity) { this.capacity = capacity; map = new HashMap<>(); }
public V get(K key) { if (!map.containsKey(key)) return null; Node node = map.get(key); moveToHead(node); return node.value; }
public void put(K key, V value) { if (map.containsKey(key)) { Node node = map.get(key); node.value = value; moveToHead(node); } else { Node newNode = new Node(key, value); if (map.size() == capacity) { map.remove(tail.key); removeTail(); } addToHead(newNode); map.put(key, newNode); } }
private void moveToHead(Node node) { if (node == head) return; removeNode(node); addToHead(node); }
private void removeNode(Node node) { if (node.prev != null) node.prev.next = node.next; else head = node.next; if (node.next != null) node.next.prev = node.prev; else tail = node.prev; }
private void addToHead(Node node) { node.prev = null; node.next = head; if (head != null) head.prev = node; head = node; if (tail == null) tail = node; }
private void removeTail() { if (tail != null) { if (tail.prev != null) tail.prev.next = null; else head = null; tail = tail.prev; } } } 三、简单测试: public class Main { public static void main(String[] args) { LRUCache<Integer, String> cache = new LRUCache<>(2); cache.put(1, "A"); cache.put(2, "B"); System.out.println(cache.get(1)); // A cache.put(3, "C"); // 淘汰 key=2 System.out.println(cache.get(2)); // null } }
|