我正在尝试动态更新HashMap中的键。
我已经创建了一个类的实例,并设置了密钥以从该类中获取值。
我试图在更新类中的值时获取要更改的键的值。我正在尝试执行的程序具有多个大型哈希图。但是,我将其简化为以下示例。
主班
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
OtherClass otherClass = new OtherClass(5);
hashMap.put(otherClass.getId(), "a string");
otherClass.setId(0); // update value in class
System.out.println(hashMap.keySet()); // outputs 5 not 0
}
}
其他班
class OtherClass {
int id;
OtherClass (int id) {
this.id = id;
}
void setId(int id) {
this.id = id;
}
int getId() {
return id;
}
}
当我更新类中的值时,HashMap中的键不会更改。
我正在尝试做的事情甚至可能吗?如果没有,我怎么能做到这一点?
问题来源:Stack Overflow
如果你想Map自动更新时id一个的OtherClass对象被修改,那么你需要编写的代码为你自己。
除非地图和对象紧密耦合,否则应保持逻辑分离,例如,通过实现属性更改跟踪。
我建议围绕PropertyChangeSupportJava Runtime Library中的类构建它。
其他类 首先,您需要启用属性更改跟踪。
我name在此答案的末尾添加了属性以改善测试代码的输出。
public final class OtherClass {
private final transient PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private int id;
private String name;
public OtherClass(int id, String name) {
this.id = id;
this.name = name;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}
public int getId() {
return this.id;
}
public void setId(int id) {
int oldId = this.id;
this.id = id;
this.pcs.firePropertyChange("id", oldId, id);
}
public String getName() {
return this.name;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
this.pcs.firePropertyChange("name", oldName, name);
}
@Override
public String toString() {
return "OtherClass[" + this.id + ", " + this.name + "]";
}
}
接下来,您需要封装,Map以便可以正确处理属性更改侦听器。
为了防止内存泄漏,重要的是要clear()在OtherMap当不再需要它,否则,以一个单一的参考OtherMap对象,它是在OtherMap将保持在map和所有在map中的对象在内存活。为了解决这个问题,我创建了object AutoCloseable,以便可以将其与try-with-resources语句一起使用,并使代码分析器帮助强调需要关闭/清除Map。
final class OtherMap implements AutoCloseable {
private final PropertyChangeListener listener = this::onPropertyChange;
private Map<Integer, OtherClass> map = new HashMap<>();
public OtherMap() {
}
public Set<Integer> keys() {
return Collections.unmodifiableSet(this.map.keySet());
}
public Collection<OtherClass> values() {
return Collections.unmodifiableCollection(this.map.values());
}
public OtherClass get(int id) {
return this.map.get(id);
}
public OtherClass add(OtherClass other) {
OtherClass prev = this.map.put(other.getId(), other);
if (prev != null)
prev.removePropertyChangeListener(this.listener);
other.addPropertyChangeListener(this.listener);
return prev;
}
public OtherClass remove(int id) {
OtherClass other = this.map.remove(id);
if (other != null)
other.removePropertyChangeListener(this.listener);
return other;
}
public void clear() {
this.map.values().forEach(other -> other.removePropertyChangeListener(this.listener));
this.map.clear();
}
private void onPropertyChange(PropertyChangeEvent evt) {
if (! "id".equals(evt.getPropertyName()))
return;
Integer oldId = (Integer) evt.getOldValue();
Integer newId = (Integer) evt.getNewValue();
if (oldId.equals(newId))
return;
OtherClass other = (OtherClass) evt.getSource();
if (this.map.putIfAbsent(newId, other) != null)
throw new IllegalStateException("Duplicate key");
if (! this.map.remove(oldId, other)) {
this.map.remove(newId);
throw new IllegalStateException();
}
}
@Override
public String toString() {
return this.map.toString();
}
@Override
public void close() {
clear();
}
}
测试
OtherClass eeny = new OtherClass(3, "Eeny");
OtherClass meeny = new OtherClass(5, "Meeny");
OtherClass miny = new OtherClass(7, "Miny");
OtherClass moe = new OtherClass(9, "Moe");
OtherMap otherMap = new OtherMap();
otherMap.add(eeny);
otherMap.add(meeny);
otherMap.add(miny);
otherMap.add(moe);
System.out.println("Before: " + otherMap);
meeny.setId(2);
otherMap.remove(miny.getId());
miny.setId(4);
System.out.println("After: " + otherMap);
输出量
Before: {3=OtherClass[3, Eeny], 5=OtherClass[5, Meeny], 7=OtherClass[7, Miny], 9=OtherClass[9, Moe]}
After: {2=OtherClass[2, Meeny], 3=OtherClass[3, Eeny], 9=OtherClass[9, Moe]}
回答来源:Stack Overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。