Я пытаюсь создать пользовательский интерфейс с HashMap
. Пользователи могут изменять значения и изменять имя клавиш, не нарушая порядок ключей. Я искал и нашел LinkedHashMap
. Который сохранил порядок ключей в большинстве случаев. Но когда я удаляю ключ и добавляю его обратно после его переименования, он всегда добавляет его до конца. Поэтому я переопределил класс LinkedHashMap
и добавил функцию changeKeyName()
.JAVA - Выполненная реализация HashMap с функцией изменения имени ключа
Теперь это работает (в моем случае), но мне было интересно, можно ли его улучшить и сделать надежным. Я только переопределил функции, которые я использовал. Какие другие функции нужно переопределить, чтобы завершить?
Заранее спасибо.
Вот код:
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: Я думаю почему не было достаточно ясно. Скажем, мы добавили ключи ниже.
{"key1":"value1"},
{"key2":"value2"},
{"key3":"value3"},
{"key4":"value4"}
И, например, я хочу изменить имя ключа «key2». Но поскольку это также пользовательский интерфейс, порядок ключей должен оставаться неизменным.
Я провел некоторое исследование, и я узнал, что, кроме удаления ключа и повторного ввода нового имени ключа с одинаковым значением, ничего не может быть сделано. Так что, если мы делаем это и изменить «key2» на «key2a»:
{"key1":"value1"},
{"key3":"value3"},
{"key4":"value4"},
{"key2a":"value2"}
И то, что я хочу это:
{"key1":"value1"},
{"key2a":"value2"},
{"key3":"value3"},
{"key4":"value4"}
Так что я просто держал ключи в ArrayList и возвращали их, когда entrySet()
и keySet()
.
** НЕТ ** изменить * ключи *; если вы это сделаете, то ваши «Map.Entry» (ы) будут в неправильных хэш-ведрах! –
@ElliottFrisch Итак, я не должен переопределять функции 'entrySet()' и 'keySet()'? Потому что я действительно не изменяю ключ, но удаляю и добавляю его с новым именем. – ossobuko
Пожалуйста, добавьте код, который вызывает * changeKeyName() * –