title: WeakHashMap vs HashMap
body: <p>In the following code example when keys are set to null and <code>System.gc()</code> is called, the <code>WeakHashMap</code> loses all mappings and is emptied.</p>
  
  <pre><code>class WeakHashMapExample {
  
  public static void main(String[] args) {
  
      Key k1 = new Key("Hello");
      Key k2 = new Key("World");
      Key k3 = new Key("Java");
      Key k4 = new Key("Programming");
  
      Map&lt;Key, String&gt; wm = new WeakHashMap&lt;Key, String&gt;();
  
  
      wm.put(k1, "Hello");
      wm.put(k2, "World");
      wm.put(k3, "Java");
      wm.put(k4, "Programming");
      k1=null;
      k2=null;
      k3=null;
      k4=null;
      System.gc();
      System.out.println("Weak Hash Map :"+wm.toString());
  
  }
  
  }
  
  class Key{
  
  private String key;
  
  public Key(String key) {
      this.key=key;
  }
  
  @Override
  public boolean equals(Object obj) {
      return this.key.equals((String)obj);
  }
  @Override
  public int hashCode() {
      return key.hashCode();
  }
  @Override
  public String toString() {
      return key;
  }
  
  }
  </code></pre>
  
  <p><code>Output: Weak Hash Map :{}</code></p>
  
  <p>When <code>WeakHashMap</code> is used along with <code>HashMap</code> and keys are set to null, the <code>WeakHashMap</code> doesn't lose its key-value mappings.</p>
  
  <pre><code>class WeakHashMapExample {
  
  public static void main(String[] args) {
  
      Key k1 = new Key("Hello");
      Key k2 = new Key("World");
      Key k3 = new Key("Java");
      Key k4 = new Key("Programming");
  
      Map&lt;Key, String&gt; wm = new WeakHashMap&lt;Key, String&gt;();
      Map&lt;Key, String&gt; hm=new HashMap&lt;Key, String&gt;();
  
      wm.put(k1, "Hello");
      wm.put(k2, "World");
      wm.put(k3, "Java");
      wm.put(k4, "Programming");
  
      hm.put(k1, "Hello");
      hm.put(k2, "World");
      hm.put(k3, "Java");
      hm.put(k4, "Programming");
      k1=null;
      k2=null;
      k3=null;
      k4=null;
      System.gc();
      System.out.println("Weak Hash Map :"+wm.toString());
      System.out.println("Hash Map :"+hm.toString());
  }
  
  }
  
  class Key{
  
  private String key;
  
  public Key(String key) {
      this.key=key;
  }
  
  @Override
  public boolean equals(Object obj) {
      return this.key.equals((String)obj);
  }
  @Override
  public int hashCode() {
      return key.hashCode();
  }
  @Override
  public String toString() {
      return key;
  }
  
  }
  </code></pre>
  
  <p>Output: 
           <code>Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming}</code>
           <code>Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}</code></p>
  
  <p>My question is why doesn't the <code>WeakHashMap</code> lose its entries in the second code example even after the keys are discarded?</p>