我想在某个时间点记录HashMap的状态。 然后用户可能会也可能不会更改它,当他们点击按钮时, 我想将HashMap的状态与先前保存的状态进行比较,看看是否有任何变化。
我可以吗
String firstState = map.toString();
然后
String secondState = map.toString();
然后比较它们是否相等?
编辑:通过州,我的意思是,如果有关于HashMap的任何变化,那么会发生变化
答案 0 :(得分:4)
判断某些内容是否真正改变的唯一方法是制作地图的副本,并在以后将其与地图进行比较:
HashMap<String, String> m = new HashMap<>();
// Populate map...
// Save the state:
HashMap<String, String> saved = new HashMap<>(m);
// Clients might modify map here...
// Test if the map was modified:
boolean modified = saved.equals(m);
HashMap.hashCode()
只能用于判断地图是否已更改(如果哈希码更改)。如果哈希码没有改变,则不能保证地图没有改变。
例如,包装地图并覆盖put()
和clear()
方法也不够,因为如果有人使用put()
更改了某个值,那么稍后他可能会调用{{ 1}}再次设置您不再存储的旧值,并且无法判断是否恢复了相同的旧值。
证明基于hascode的方法错误:
如果地图包含put()
个值作为值,我们可以轻松地将值更改为具有相同哈希码的其他String
,这样String
不会发生变化
例如,以下HashMap.hashCode()
都具有相同的哈希码,但它们不相等:
String
证明基于包装器的方法错误:
String s1 = ""; // Hashcode = 0
String s2 = "\0"; // Hashcode = 0
String s3 = "\0\0"; // Hashcode = 0
HashMap<String, String> m = new HashMap<>();
m.put("one", s1);
m.put("one", s2); // This does not change m.hashCode() yet its content changes!
答案 1 :(得分:2)
你可以比较它的&#39;哈希值
int hash1 = map.hashCode();
// do something
int hash2 = map.hashCode();
JavaDoc声明:
地图的哈希码被定义为地图的entrySet()视图中每个条目的哈希码的总和
答案 2 :(得分:1)
或者,您可以将地图包装到一个包装类中,该类记录上次修改时间,无论如何。使用该值,您可以检查是否有修改。
如果您决定使用hashCode值来解决此问题,则应忽略可能存在哈希冲突的可能性。
但在回答问题时,我认为有一个重要方面需要考虑 - 键的数量。如果没有太多的键,'copy construction + equals'方法将是基于包装器的解决方案的一个很好的替代方案。 (首先是make和old copy,然后将它与map的当前状态进行比较)但是如果键太多,这两个操作可能会产生很大的开销。
答案 3 :(得分:0)
您可以复制地图。
HashMap old = new HashMap(map);
然后检查旧地图是否包含与当前地图相同的键/值绑定,假设&#39;等于&#39;正确实现了值。
if (!old.equals(map)) {
System.out.println("Something changed");
}