I am trying to create a user interface with a HashMap
. Users could change values and change the name of the keys without disturbing the order of the keys. I searched and found the LinkedHashMap
. Which kept the order of the keys in most cases. But when I remove a key and add it back after renaming it, it always adds it to the end. So I've overridden LinkedHashMap
class and added a changeKeyName()
function.
Now it works (in my case) but I was wondering if it could be improved and made foolproof. I only overridden the functions I was using. What other functions have to be overridden in order make it complete?
Thanks in advance.
Here is the code:
private static class OrderedHashMap<K, V> extends LinkedHashMap<K, V> {
ArrayList<K> keys = new ArrayList<K>();
@Override
public V put(K key, V value) {
if (!keys.contains(key))
keys.add(key);
return super.put(key, value);
}
@Override
public V remove(Object key) {
keys.remove(key);
return super.remove(key);
}
@Override
public Set<K> keySet() {
LinkedHashSet<K> keys = new LinkedHashSet<K>();
for (K key : this.keys) {
keys.add(key);
}
return keys;
}
public void changeKeyName(K oldKeyName, K newKeyName) {
int index = keys.indexOf(oldKeyName);
keys.add(index, newKeyName);
keys.remove(keys.get(index + 1));
V value = super.get(oldKeyName);
super.remove(oldKeyName);
super.put(newKeyName, value);
}
@Override
public Set<Map.Entry<K, V>> entrySet() {
final OrderedHashMap<K, V> copy = this;
LinkedHashSet<Map.Entry<K, V>> keys = new LinkedHashSet<Map.Entry<K, V>>();
for (final K key : this.keys) {
final V value = super.get(key);
keys.add(new Map.Entry<K, V>() {
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
return copy.put(getKey(), value);
}
});
}
return keys;
}
}
EDIT: I think the why wasn't clear enough. Let's say we added the keys below.
{"key1":"value1"},
{"key2":"value2"},
{"key3":"value3"},
{"key4":"value4"}
And for example I want to change the key name of the "key2". But as this is also a user interface, order of the keys should stay the same.
I made some research and I found out that apart from removing the key and re-puting the new key name with the same value, nothing could be done. So if we do that and change "key2" to "key2a":
{"key1":"value1"},
{"key3":"value3"},
{"key4":"value4"},
{"key2a":"value2"}
And what I want is this:
{"key1":"value1"},
{"key2a":"value2"},
{"key3":"value3"},
{"key4":"value4"}
So I just kept the keys in a ArrayList and returned them when entrySet()
and keySet()
methods are called.