哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希表底层是由数组和链表组成,数组中的每一个值都是一个链表,我们可以理解为“链表的数组”。
HashMap就是用哈希表来实现的,当我们调用put(key,value)方法时,哈希表使用key.hashCode()%tableSize,计算得出来的值就是数组的下标,因不同key算出来的下标值可能相同,所以即使数组的下标相同,不同的key也可以使用链表链接起来,这样就形成了如下图所示的一个结构,这就是哈希表。
代码实现如下:
Node类:
public class Node {
// key、value模拟键值对的数据
public Integer key;
public String value;
// 下一节点的引用
public Node next;
public Node() {
}
public Node(int key, String value) {
this.key = key;
this.value = value;
}
}
LinkedList类:
public class LinkedList { // 根节点 private Node root; public LinkedList() { root = new Node(); } /** * 添加数据,key值必须唯一,如果重复值将被覆盖 * @param key */ public void add(int key, String value) { Node newNode = new Node(key, value); Node current = root; while (current.next != null) { if(current.next.key == key) { current.next.value = value; return; } current = current.next; } current.next = newNode; } /** * 删除数据 * @param key * @return */ public boolean delete(int key) { Node current = root; while (current.next != null) { if(current.next.key == key) { current.next = current.next.next; return true; } current = current.next; } return false; } /** * 根据key获取value * @param key * @return */ public String get(int key) { Node current = root; while (current.next != null) { if(current.next.key == key) { return current.next.value; } current = current.next; } return null; } /** * 遍历链表,列出所有数据 * @return */ public String list() { String str = ""; Node current = root.next; while (current != null) { str += "(" + current.key + "," + current.value + "),"; current = current.next; } return str; } @Override public String toString() { return list(); } }
HashTable类:测试类:// 哈希表 public class HashTable { // 链表数组,数组的每一项都是一个链表 private LinkedList[] arr; // 数组的大小 private int maxSize; /** * 空参构造,默认数组大小为10 */ public HashTable() { maxSize = 10; arr = new LinkedList[maxSize]; } /** * 带参构造,数组大小自定义 * @param maxSize */ public HashTable(int maxSize) { this.maxSize = maxSize; arr = new LinkedList[maxSize]; } /** * 添加数据,key值必须唯一 * @param key * @param value */ public void put(int key, String value) { int index = getHashIndex(key); if(arr[index] == null) { arr[index] = new LinkedList(); } arr[index].add(key, value); } /** * 删除数据 * @param key * @return */ public boolean delete(int key) { int index = getHashIndex(key); if(arr[index] != null) { return arr[index].delete(key); } return false; } /** * 根据key获取value * @param key * @return */ public String get(int key) { int index = getHashIndex(key); if(arr[index] != null) { return arr[index].get(key); } return null; } /** * 获取数组下标 * @param key * @return */ private int getHashIndex(Integer key) { return key.hashCode() % maxSize; } /** * 遍历数组中所有链表的数据 * @return */ public String list() { String str = "[ "; for (int i = 0; i < maxSize; i++) { if(arr[i] != null) { str += arr[i].toString(); } } str = str.substring(0, str.length()-1); str += " ]"; return str; } @Override public String toString() { return list(); } }
public class Test { public static void main(String[] args) { HashTable table = new HashTable(20); table.put(5, "aaa"); table.put(8, "bbb"); table.put(3, "ccc"); table.put(8, "bbb"); table.put(2, "ddd"); table.put(9, "eee"); System.out.println(table); System.out.println(table.get(3)); System.out.println(table.delete(2)); System.out.println(table); } }