<p>I know there is a <code>WeakHashMap</code> in <code>java.util</code>, but since it uses <code>WeakReference</code>s for everything, which is only referenced by this <code>Map</code>, referenced objects will get lost on the next GC cycle. So it's nearly useless if you want to cache random data, which is very likely to be requested again without being Hard-linked the rest of the time. The best solution would be a map, which uses <code>SoftReference</code>s instead, but I didn't find one in the Java RT Package.</p>

Edit (Aug. 2012):
It turns out that currently the best solution are probably Guava 13.0's
```
Cache
```
classes, explained on
Guava's Wiki
- that's what I'm going to use.
It even supports building a
```
SoftHashMap
```
(see
```
CacheBuilder.newBuilder().softKeys()
```
), but it is probably not what you want, as Java expert Jeremy Manson explains (below you'll find the link).
Not that
I know of
(Nov. 2008), but you kind find some implementation of
```
SoftHashMap
```
on the net.
Like this one:
```
SoftHashMap
```
or
this one
.
Edit (Nov. 2009)
As
Matthias
mentions in the comments, the
Google Guava
MapMaker
does use SoftReferences:
A
```
ConcurrentMap
```
builder, providing any combination of these features:
soft or weak keys,
soft or weak values,
timed expiration, and
on-demand computation of values.
As mentioned in
this thread
, another JSR166y candidate:
jsr166y.ConcurrentReferenceHashMap
It provides an alternative concurrent reference map to the Google implementation (which relies on a background thread to evict entries)
Edit (August 2012)
The Google implementation uses a background thread only when timed expiration of entries is requested. In particular, it simply uses
```
java.util.Timer
```
, which is not so intrusive as having a separate background thread.
Jeremy Manson recommends, for any cache, using this feature to avoid the dangers of SoftReference:
http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html
There's another implementation from
Apache Commons
, namely
org.apache.commons.collections.map.ReferenceMap
; it does not support timed removal, but it does support choosing whether keys should be compared by identity or by equality. Moreover, this implementation is not concurrent - it can be made synchronized, but that works less well under accesses from multiple threads.