zoukankan      html  css  js  c++  java
  • 基于Java的HashMap和HashSet实现

    一、Map接口类:

     1 import java.util.Iterator;
     2 
     3 public interface IMap<K, V> {
     4     /* 清除所有键值对 */
     5     void clear();
     6 
     7     /* key是否已经存在 */
     8     boolean containsKey(K key);
     9 
    10     /* value是否存在 */
    11     boolean containsValue(V value);
    12 
    13     /* 根据key获得value */
    14     V get(K key);
    15 
    16     /* map是否为空 */
    17     boolean isEmpty();
    18 
    19     /* 所有key组成的数组 */
    20     MyHashSet<K> keySet();
    21 
    22     /* 存入键值对 */
    23     void put(K key, V value);
    24 
    25     /* 把另外一个map中的所有键值对存入到当前map中 */
    26     void putAll(IMap<? extends K, ? extends V> map);
    27 
    28     /* 根据key删除一个键值对 */
    29     V remove(K key);
    30 
    31     /* 键值对的个数 */
    32     int size();
    33 
    34     /* 所有的value组成的数组 */
    35     V[] values();
    36 
    37     Iterator<MyHashMap.Node> iterator();
    38 }
    View Code

    二、HashSet接口类:

     1 import java.util.Iterator;
     2 
     3 public interface IHashSet<E> {
     4     void add(E key);
     5 
     6     void remove(E key);
     7 
     8     void clear();
     9 
    10     boolean contains(E key);
    11 
    12     boolean isEmpty();
    13 
    14     int size();
    15 
    16     Iterator<E> iterator();
    17 }
    View Code

    三、HashMap类:

      1 import java.util.Iterator;
      2 
      3 public class MyHashMap<K, V> implements IMap<K, V> {
      4     private int length = 16;
      5 
      6     private Node[] buckets = new Node[length];//
      7     private int size;
      8 
      9     @Override
     10     public void clear() {
     11         for (int i = 0; i < buckets.length; i++) {
     12             buckets[i] = null;
     13         }
     14     }
     15 
     16     @Override
     17     public boolean containsKey(K key) {
     18         int index = hash1(key);
     19         if (buckets[index] == null) {
     20             return false;
     21         } else {
     22             Node<K, V> p = buckets[index];// 相当于在链表中找key
     23             while (p != null) {
     24                 K k1 = p.key;
     25                 // Java == 比较的是地址
     26                 // 借用java机制,hashcode和equals都来自于Object,用户可以改写这两个方法——制定对象相等的规则
     27                 if (k1 == key || (k1.hashCode() == key.hashCode() && k1.equals(key))) {
     28                     return true;
     29                 }
     30                 p = p.next;
     31             }
     32         }
     33 
     34         return false;
     35     }
     36 
     37     @Override
     38     public boolean containsValue(V value) {
     39         for (int i = 0; i < buckets.length; i++) {
     40             if (buckets[i] != null) {
     41                 Node<K, V> p = buckets[i];
     42                 while (p != null) {
     43                     if (p.value.equals(value))
     44                         return true;
     45                 }
     46             }
     47         }
     48         return false;
     49     }
     50 
     51     @Override
     52     public V get(K key) {
     53         int index = hash1(key);
     54         if (buckets[index] == null) {
     55             return null;
     56         } else {
     57             Node<K, V> p = buckets[index];
     58             while (p != null) {
     59                 K k1 = p.key;
     60                 if (k1 == key || (k1.hashCode() == key.hashCode() && k1.equals(key))) {
     61                     return p.value;
     62                 }
     63                 p = p.next;
     64             }
     65         }
     66         return null;
     67     }
     68 
     69     @Override
     70     public boolean isEmpty() {
     71         return size == 0;
     72     }
     73 
     74     @Override
     75     public MyHashSet<K> keySet() {
     76         MyHashSet<K> set = new MyHashSet<>();
     77         for (int i = 0; i < buckets.length; i++) {
     78             if (buckets[i] != null) {
     79                 Node<K, V> p = buckets[i];
     80                 while (p != null) {
     81                     set.add(p.key);
     82                     p = p.next;
     83                 }
     84             }
     85         }
     86         return set;
     87     }
     88 
     89     @Override
     90     public void put(K key, V value) {
     91         Node<K, V> node = new Node<>(key, value);
     92         int index = hash1(key);// 算出在桶中的位置
     93         if (buckets[index] == null) {// 桶中没有东西
     94             buckets[index] = node;
     95             size++;
     96         } else {
     97             Node<K, V> p = buckets[index];// 链表的表头找到
     98             while (p != null) {
     99                 K k1 = p.key;
    100                 if (key == k1 || key.hashCode() == k1.hashCode() && key.equals(k1)) {
    101                     p.value = value;// 存在相同的key,则更新value
    102                     break;
    103                 }
    104                 if (p.next == null) {
    105                     p.next = node;
    106                     size++;
    107                     break;
    108                 }
    109                 p = p.next;
    110             }
    111 
    112         }
    113     }
    114 
    115     private int hash1(K key) {
    116         // return key.hashCode() % length;
    117         int h = 0;
    118         int seed = 31;// 素数
    119         String s = key.toString();
    120         for (int i = 0; i != s.length(); ++i) {
    121             h = seed * h + s.charAt(i);
    122         }
    123         return h % length;
    124     }
    125 
    126     @Override
    127     public void putAll(IMap<? extends K, ? extends V> map) {
    128 
    129     }
    130 
    131     @Override
    132     public V remove(K key) {
    133         int index = hash1(key);// 先定桶的位置
    134         if (buckets[index] == null) {
    135             return null;
    136         } else {
    137             Node<K, V> p = buckets[index];// 找到表头
    138             Node<K, V> pre = p;
    139 
    140             while (p != null) {
    141                 K k1 = p.key;
    142                 if (k1.hashCode() == key.hashCode() && k1.equals(key)) {
    143                     // 移除
    144                     if (p == pre) {
    145                         buckets[index] = pre.next;
    146                     } else {
    147                         pre.next = p.next;
    148                     }
    149                     size--;
    150                     return p.value;
    151                 }
    152                 pre = p;
    153                 p = p.next;
    154             }
    155         }
    156         return null;
    157     }
    158 
    159     @Override
    160     public int size() {
    161         return size;
    162     }
    163 
    164     @Override
    165     public V[] values() {
    166         return null;
    167     }
    168 
    169     private class MapInterator implements Iterator<Node> {
    170         int i = 0;
    171         Node p = buckets[0];
    172 
    173         @Override
    174         public boolean hasNext() {
    175             while (this.i < length && p == null) {
    176                 this.i++;
    177                 if (this.i == length)
    178                     p = null;
    179                 else
    180                     p = buckets[this.i];
    181             }
    182             // i是一个非空的桶,p是链表头
    183             return p != null;
    184         }
    185 
    186         @Override
    187         public Node next() {
    188             Node res = p;
    189             p = p.next;
    190             return res;
    191         }
    192     }
    193 
    194     @Override
    195     public Iterator<Node> iterator() {
    196         return new MapInterator();
    197     }
    198 
    199     @Override
    200     public String toString() {
    201         StringBuilder sb = new StringBuilder();
    202         for (int i = 0; i < buckets.length; i++) {
    203             if (buckets[i] != null) {
    204                 Node<K, V> p = buckets[i];
    205                 while (p != null) {
    206                     sb.append("(" + p.key + "," + p.value + "),");
    207                     p = p.next;
    208                 }
    209             }
    210         }
    211         return sb.toString();
    212     }
    213 
    214     public class Node<K, V> {
    215         public K key;
    216         public V value;
    217 
    218         public Node(K key, V value) {
    219             this.key = key;
    220             this.value = value;
    221         }
    222 
    223         private Node next;
    224 
    225         @Override
    226         public String toString() {
    227             return "BSTNode{" + "key=" + key + ", value=" + value + '}';
    228         }
    229     }
    230 }
    View Code

    四、HashSet类:

     1 import java.util.Iterator;
     2 
     3 public class MyHashSet<E> implements IHashSet<E> {
     4     private MyHashMap<E, E> map = new MyHashMap<>();
     5 
     6     @Override
     7     public void add(E key) {
     8         map.put(key, null);
     9     }
    10 
    11     @Override
    12     public void remove(E key) {
    13         map.remove(key);
    14     }
    15 
    16     @Override
    17     public void clear() {
    18         map.clear();
    19     }
    20 
    21     @Override
    22     public boolean contains(E key) {
    23         return map.containsKey(key);
    24     }
    25 
    26     @Override
    27     public boolean isEmpty() {
    28         return map.isEmpty();
    29     }
    30 
    31     @Override
    32     public int size() {
    33         return map.size();
    34     }
    35 
    36     @Override
    37     public Iterator<E> iterator() {
    38         Iterator<MyHashMap.Node> iter = map.iterator();
    39         return new Iterator<E>() {
    40             @Override
    41             public boolean hasNext() {
    42                 return iter.hasNext();
    43             }
    44 
    45             @Override
    46             public E next() {
    47                 return (E) iter.next().key;
    48             }
    49         };
    50     }
    51 
    52     @Override
    53     public String toString() {
    54         Iterator<MyHashMap.Node> iterator = map.iterator();
    55         StringBuilder sb = new StringBuilder();
    56         while (iterator.hasNext()) {
    57             sb.append(iterator.next().key + ",");
    58         }
    59         return sb.toString();
    60     }
    61 }
    View Code

    五、HashMap优化:

      1、扩容:如果当表中的75%已经被占用,即视为需要扩容了。

      2、如果冲突造成的链表长度超过8的时候,就要转为红黑树存储。

      3、hash函数优化。h = key.hashCode(); h^(h>>16); h % length。

  • 相关阅读:
    通过代码去执行testNG用例
    启动jenkins服务错误
    linux 添加用户到sudo中
    通过jenkins API去build一个job
    iptables
    比较git commit 两个版本之间次数
    linux awk命令详解
    cron和crontab
    工作随笔——CentOS6.4支持rz sz操作
    Jenkins进阶系列之——15Maven获取Jenkins的Subversion的版本号
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10389610.html
Copyright © 2011-2022 走看看