我目前正在编写一些我非常关注性能和内存使用情况的内容。
我想知道这个问题,我正在努力做出决定。想象一下这种情况:
我需要将某个Class(Location)和一个Integer关联到一个String(让我们说一个名字)。所以名称有一个Id和一个位置......
最好的方法是什么?
首先:创建两个哈希映射
HashMap<String, Location> one = new HashMap<String, Location>
HashMap<String, Integer> two = new HashMap<String, Integer>
第二:仅使用一个hashmap并创建一个新类
HashMap<String, NewClass> one = new HashMap<String, NewClass>
其中NewClass包含:
class NewClass {
Location loc;
Integer int;
}
答案 0 :(得分:2)
如果您希望每个String都与BOTH位置和整数耦合,请使用新类,调试和维护将更加容易,因为它是有意义的。字符串X连接到位置和整数。它可以确保您减少错误(例如只插入其中一个,或只删除一个),并且更易读。
如果关联松散,并且某些字符串可能只需要位置,而某些字符串只需要整数 - 使用两个映射可能更可取,因为未来的代码读者(包括您在3个月内)将无法理解这是什么新的class以及String X需要有位置的原因。
TL; DR:
String->MyClass
如果每个字符串始终与位置和整数String->Integer, String->Location
如果每个字符串独立地与位置和整数相关联。答案 1 :(得分:2)
如果你总是需要同时检索Id和Location,第一种方法需要2次Hash查找,而第二种方法只需要1次。在这种情况下,第二种方法应该有更好的性能。
为了测试我做了下面的简单测试:
// create 2 hashes with 1M entries
for (int i = 0; i < 1000000; i++){
String s = new BigInteger(80, random).toString(32);
hash1.put(s, s);
hash2.put(s, new BigInteger(80, random).intValue());
}
// create 1 hash with 1M entries
for (int i = 0; i < 1000000; i++){
String s = new BigInteger(80, random).toString(32);
NewClass n = new NewClass();
n.i = new BigInteger(80, random).intValue();
n.loc = s;
hash3.put(s, n);
}
// 5M lookups
long start = new Date().getTime();
for (int i = 0; i < 5000000; i++){
String s = "AAA";
hash1.get(s);
hash2.get(s);
}
System.out.println("Approach 1 (2 hashes): " + (new Date().getTime() - start));
// 5M lookups
long start2 = new Date().getTime();
for (int i = 0; i < 5000000; i++){
String s = "BBB";
hash3.get(s);
}
System.out.println("Approach 2 (1 hash): " + (new Date().getTime() - start2));
在我的计算机上运行,结果是:
测试非常简单,如果你要考虑严重的性能问题,你应该深入研究这个问题,考虑内存占用,对象创建成本等其他方面。但是,无论如何,使用2个哈希值将增加总查找时间。