Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to effectively use a String as a WeakHashMap key in Java, or an alternative solution

I am managing a project in Java that stores user data. Users can be online, or offline. When users are online, their data is loaded into the data object for easy accessibility, and offloaded when they log off.

However, for offline users, in the interests of preventing data loss from concurrent access of data from multiple commands manipulating the data at the same time, I store a weakhashmap as a cache of the loaded user data objects. Should anything need to access an offline data object to modify it, the system will check the cache first before loading it from file.

The only thing that I can think of how to store them is by a string key, which represents the users username. But because of how java works, that does not always seem to work due to the VM's string caching system.

Originally I thought of using a string wrapper, but again because of how hashmaps work (by use of hashcode), creating a new string wrapper would not get me the value i need, and if i stored the string wrappers, that would defeat the purpose by storing a strong reference to the key at all times (preventing the removal of the key from the weakhashmap).

Maybe I'm just not understanding how the weakhashmap is supposed to be used :S If this isn't how the weakhashmap is supposed to be used, I'm open to accept other ideas of how to do what I wish.

like image 446
CorrieKay Avatar asked Apr 13 '14 03:04

CorrieKay


1 Answers

The reason it behaves unpredictably is explained in the Javadoc for WeakHashMap in the last sentence of this paragraph:

This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a lookup of that key in a WeakHashMap at some later time and be surprised that its entry has been removed. This class will work perfectly well with key objects whose equals methods are not based upon object identity, such as String instances. With such recreatable key objects, however, the automatic removal of WeakHashMap entries whose keys have been discarded may prove to be confusing.

What you really want is a map where the entries are removed when the values get garbage collected, rather than when the keys get garbage collected - that is, for which the values are weak, rather than for which the keys are weak. You can find help on that issue at this question:

Java Weak Hash Map - Need to remove entry based on weakness of value, not key

like image 185
Warren Dew Avatar answered Oct 26 '22 10:10

Warren Dew