我想构建一个Date对象的HashMap,所以每当我有两个不同的Date对象具有相同的Date值(day,month,year,..)时,Hashmap就不会用新的值替换过去的值。
示例:
Date x = new Date();
Date y = new Date();
HashMap<Date,Integer> hm = new HashMap<Date,Integer>();
hm.put(x,1);
hm.put(y,3);
System.out.println(hm.get(x));
System.out.println(hm.get(y));
在这个例子中,他们都打印3.我想确保他们打印1然后3。
我已经考虑过将Hashmap中的键值作为每个日期的对象引用(因为它们会有所不同),那么如何强制执行该对象呢?
或者有更好的方法吗?
答案 0 :(得分:5)
您应该使用java.util.IdentityHashMap执行此任务。这样您就可以拥有equals
,但Map
中有不同的对象。
编辑: 你的例子:
Date x = new Date();
Date y = new Date();
Map<Date,Integer> hm = new IndentityHashMap<Date,Integer>();
hm.put(x,1);
hm.put(y,3);
assert hm.size() == 2: hm.size();
正如@BoristheSpider所指出的,当您丢失原始对象的引用时,这可能不是最好的数据结构。在这种情况下,MultiMap
(例如guava)或List
个Entry
s / Pair
s / Tuple
可能是根据用例更好的选择。 (前者适用于您希望所有值都属于某些equals
个键的情况,后者是访问所有键/值对,而不是按键搜索。)
如果您只想将Map
作为“数组”使用随机访问某些或所有(存储的)密钥,IdentityHashMap
是一个不错的选择。
答案 1 :(得分:0)
更好的解决方案是使用唯一的时间戳。这将确保您可以通过具有相同的时间戳来检索值。
private static final AtomicLong MILLIS = new AtomicLong();
public static Date newDate() {
long now = System.currentTimeMillis();
for(;;) {
long prev = MILLIS.get();
if (prev >= now)
now = prev + 1;
if (MILLIS.comapreAndSet(prev, now))
return new Date(now);
}
}
如果您使用此日期工厂,则每个数据都是唯一的,并且尽可能接近实际时间。
Date x = newDate();
Date y = newDate();
Map<Date,Integer> hm = new HashMap<>();
hm.put(x,1);
hm.put(y,3);
System.out.println(hm.get(x));
System.out.println(hm.get(y));