我正在编写一个字典,它大量使用String作为Map<String, Index>
中的密钥。我关心的是HashMap
和TreeMap
中的哪一个会在搜索地图中的关键字时获得更好(更快)的效果?
答案 0 :(得分:22)
鉴于没有太多的碰撞,hashmaps会给你o(1)性能(有很多colissions,这可能降级到潜在的O(n),其中N是任何一个桶中的条目数(colissions))。另一方面,如果您想要某种平衡的树结构来生成O(logN)检索,则使用TreeMaps。所以它真的取决于你的特定用例。但是,如果您只想访问元素,则无论其顺序如何都使用HashMap
答案 1 :(得分:15)
public class MapsInvestigation {
public static HashMap<String, String> hashMap = new HashMap<String, String>();
public static TreeMap<String, String> treeMap = new TreeMap<String, String>();
public static ArrayList<String> list = new ArrayList<String>();
static {
for (int i = 0; i < 10000; i++) {
list.add(Integer.toString(i, 16));
}
}
public static void main(String[] args) {
System.out.println("Warmup populate");
for (int i = 0; i < 1000; i++) {
populateSet(hashMap);
populateSet(treeMap);
}
measureTimeToPopulate(hashMap, "HashMap", 1000);
measureTimeToPopulate(treeMap, "TreeMap", 1000);
System.out.println("Warmup get");
for (int i = 0; i < 1000; i++) {
get(hashMap);
get(treeMap);
}
measureTimeToContains(hashMap, "HashMap", 1000);
measureTimeToContains(treeMap, "TreeMap", 1000);
}
private static void get(Map<String, String> map) {
for (String s : list) {
map.get(s);
}
}
private static void populateSet(Map<String, String> map) {
map.clear();
for (String s : list) {
map.put(s, s);
}
}
private static void measureTimeToPopulate(Map<String, String> map, String setName, int reps) {
long start = System.currentTimeMillis();
for (int i = 0; i < reps; i++) {
populateSet(map);
}
long finish = System.currentTimeMillis();
System.out.println("Time to populate " + (reps * map.size()) + " entries in a " + setName + ": " + (finish - start));
}
private static void measureTimeToContains(Map<String, String> map, String setName, int reps) {
long start = System.currentTimeMillis();
for (int i = 0; i < reps; i++) {
get(map);
}
long finish = System.currentTimeMillis();
System.out.println("Time to get() " + (reps * map.size()) + " entries in a " + setName + ": " + (finish - start));
}
}
给出了这些结果:
Warmup populate
Time to populate 10000000 entries in a HashMap: 230
Time to populate 10000000 entries in a TreeMap: 1995
Warmup get
Time to get() 10000000 entries in a HashMap: 140
Time to get() 10000000 entries in a TreeMap: 1164
答案 2 :(得分:11)
HashMap是O(1)(通常)用于访问; TreeMap是O(log n)(保证)。
这假设您的密钥对象是不可变的,并且具有正确编写的equals和hashCode方法。有关如何正确覆盖equals和hashCode,请参阅Joshua Bloch的“Effective Java”chapter 3。
答案 3 :(得分:8)
a HashMap
是O(1)平均值,所以它应该更快,对于大型地图可能会有更好的吞吐量。
但是,当负载平衡变得过高时,HashMap
需要重新散列。重复是O(n),因此在程序生命的任何时候,由于重新散列,您可能会遭受意外的性能损失,这在一些应用程序中可能是至关重要的[高延迟]。如果latency是个问题,那么在使用HashMap
之前请三思而后行!
HashMap
也容易受到差的散列函数的影响,如果使用的许多项被散列到同一个地方,这可能会导致O(n)。
答案 4 :(得分:1)
HashMap速度更快。但是,如果您经常需要按字母顺序处理字典,那么使用TreeMap会更好,因为每次需要按字母顺序处理时,您都需要对所有单词进行排序。
对于您的应用程序,HashMap是更好的选择,因为我怀疑您是否经常需要按字母顺序排序的列表。