title: Guava CacheBuilder or MapMaker with Weak/Soft usage
body: <p>I'm not used to deal with Soft and Weak references in Java but i understand the principle since i'm used to deal with datagrids like Gemfire, which provide overflow to hdd features when memory is full, probably using soft references or something similar i guess.</p>
  
  <p>What i don't understand in Guava is that it provides methods to make the keys soft/weak, and the values soft/weak.</p>
  
  <p>I just wonder what's the point of creating soft keys with non-soft values for exemple?
  I mean, when the soft references start to be collected, we can't find anymore the entry by its key, so why would we like the values to stay in the map?</p>
  
  <p>Can someone give us some usecases with:</p>
  
  <ul>
  <li>Weak key / soft values </li>
  <li>Weak key / normal values </li>
  <li>Soft key / weak values </li>
  <li>Soft key / normal values</li>
  </ul>
  
  <p>Thanks</p>
  
  <hr>
  
  <p><strong>Edit</strong>
  I'm not sure my question is precise enough so what i'd like to know is:</p>
  
  <ul>
  <li>when a key is collected (weak/soft), what happens to the value (non weak/soft)</li>
  <li>when a value is collected (weak/soft), what happens to the key</li>
  <li>Are entries with a missing part (key or value) kept in the cache? </li>
  <li>And is there any usecase when you want such entries to stay in the cache.</li>
  </ul>
  
  <hr>
  
  <p><strong>Edit:</strong>
  As discussed on Kevin Bourillon's answer, finally i think i understand why using soft keys doesn't mean anything.
  Here's why:</p>
  
  <pre><code>static class KeyHolder {
      final private String key;
      public KeyHolder(String key) {
          this.key = key;
      }
      public String getKey() {
          return key;
      }
      @Override
      public boolean equals(Object o) {
          KeyHolder that = (KeyHolder)o;
          boolean equality = this.getKey().equals(that.getKey());
          return equality;
      }
      @Override
      public int hashCode() {
          return key != null ? key.hashCode() : 0;
      }
      @Override
      public String toString() {
          return "KeyHolder{" +
                  "key='" + key + '\'' +
                  '}';
      }
  }
  
  public static void main(String[] args) {
      System.out.println("TESTING WEAK KEYS");
      testMap( new MapMaker().weakKeys().&lt;KeyHolder,String&gt;makeMap() );
  
  
      System.out.println("\n\n");
      System.out.println("TESTING SOFT KEYS");
      testMap(new MapMaker().softKeys().&lt;KeyHolder, String&gt;makeMap());
  
  
      System.out.println("\n\n");
      System.out.println("TESTING SOFT REFERENCES");
      KeyHolder key1 = new KeyHolder("toto");
      KeyHolder key2 = new KeyHolder("toto");
      SoftReference&lt;KeyHolder&gt; softRef1 = new SoftReference&lt;KeyHolder&gt;(key1);
      SoftReference&lt;KeyHolder&gt; softRef2 = new SoftReference&lt;KeyHolder&gt;(key2);
      System.out.println( "equals keys? " + key1.equals(key2) );
      System.out.println( "equals ref? " + softRef1.equals(softRef2) );
  }
  
  private static void testMap(Map&lt;KeyHolder,String&gt; map) {
      KeyHolder strongRefKey = new KeyHolder("toto");
      KeyHolder noStrongRefKey = new KeyHolder("tata");
      map.put(strongRefKey,"strongRef");
      map.put(noStrongRefKey,"noStrongRefKey");
      // we replace the strong reference by another key instance which is equals
      // this could happen for exemple in case of serialization/deserialization of the key
      noStrongRefKey = new KeyHolder("tata");
      System.gc();
      System.out.println( "strongRefKey = " + map.get(strongRefKey) );
      System.out.println( "noStrongRefKey = " + map.get(noStrongRefKey) );
      System.out.println( "keyset = " + map.keySet() );
  }
  </code></pre>
  
  <p>This code produces the output:</p>
  
  <pre><code>TESTING WEAK KEYS
  strongRefKey = strongRef
  noStrongRefKey = null
  keyset = [KeyHolder{key='toto'}]
  
  
  
  TESTING SOFT KEYS
  strongRefKey = strongRef
  noStrongRefKey = null
  keyset = [KeyHolder{key='tata'}, KeyHolder{key='toto'}]
  
  
  
  TESTING SOFT REFERENCES
  toto == toto -&gt; true
  equals keys? true
  equals ref? false
  </code></pre>
  
  <p>As you can see, with the (deprecated) soft keys map, the KeyHolder containing "tata" still exists in the map.
  But notice that i'm still not able to find my entry with a newly created key "<code>new KeyHolder("tata");</code>"
  <strong>This is because, my keys are meaningfully equals, but the reference wrappers around them are not equals because their equals method is not overriden in Guava!</strong>
  In this case, yes, softKeys doesn't mean anything since you absolutly need to keep an identity reference to that key to be able to retrieve it.</p>