2017-04-03 65 views
-4

根据的Java 8this链接,以避免在地图(HashMap, LinkedHashMap, and ConcurrentHashMap)碰撞使用平衡树,而不是LinkedList实现。TreeMap的HashMap中VS在java8

那么有什么区别,如果:

  1. 两者(TreeMap和其他地图(HashMap, LinkedHashMap, and ConcurrentHashMap)使用自我平衡树,为最坏的情况下可访问性是相同的时候实现
  2. 排序的entry我能实现如下:

    public <K extends Comparable,V extends Comparable> LinkedHashMap<K,V> sortByKeys(LinkedHashMap<K,V> map){ 
        List<K> keys = new LinkedList<K>(map.keySet()); 
        Collections.sort(keys, (Comparator<? super K>) new Comparator<String>() { 
         @Override 
         public int compare(String first, String second) {     
          return first.compareTo(second); 
         } 
        }); 
    } 
    

除分类和可访问性TreeMap的其他属性还有哪些?

+0

这不是计算器一个很好的问题,树状图是当你需要时自动排序(例如字典),你似乎已经知道地图。 –

+4

您的观点是什么?在#1中,你暗示没有区别,因为*最差情况*是相同的。对你而言,这是非常悲观的,假设你总是有*最坏的情况*。在#2中,你说你可以随时在需要时对键进行排序,但排序很昂贵。一个'TreeMap'总是被排序的,所以如果'Map'不断被修改,并且你不断需要结果,那么就会有巨大的性能差异。 'HashMap'性能更好(假设使用小数散列函数)并且不需要密钥* * *。如果要求按键顺序,'TreeMap'会更好。 – Andreas

+2

...此外,无论键值是否在地图中,“TreeMap”都可以为您提供给定键值的相邻键。一个'HashMap'不能做到这一点。排序后的列表不能做到这一点,除非您先浪费时间对列表进行排序,然后再执行二进制搜索*。 – Andreas

回答

0
  1. 两者(TreeMap和其他地图(HashMap的,LinkedHashMap的,而ConcurrentHashMap的)得到了采用自平衡树实现,最坏的情况下可访问性是一样的。

    在JDK7老JDK recalculate bucket indexsize >= threshold,并且每个桶impelements作为linked list,但在jdk8是调整balancing-trees和impelemented作为Red-Black Tree

    每个桶把这样的事情的时候到HasMap在JDK7,然后查找节点只有一个桶是O(N)。当把这样的事情到HasMap在jdk8但关键实施Comparable

    class Foo{ 
        int hashCode(){ 
         return 0; 
        } 
    } 
    Foo first=new Foo(); 
    Foo last=new Foo(); 
    map.put(first,"anything"); 
    map.put(last,"anything"); 
    map.get(last | first);// O(N) 
    

    只有一个水桶。那么查找节点是O(log(N)),但是如果i是相同的,则查找节点将回退到O(N)。

    class Foo implements Comparable<Foo> { 
        private int i; 
    
        public Foo(int i) { 
    
         this.i = i; 
        } 
    
        public int hashCode() { 
         return 0; 
        } 
    
        @Override 
        public int compareTo(Foo that) { 
         return i - that.i; 
        } 
    } 
    
    Foo first=new Foo(1); 
    Foo last=new Foo(2); 
    map.put(first,"anything"); 
    for(int i=2;i<threshold;i++) 
        map.put(new Foo(i + 1), "anything"); 
    map.put(last,"anything"); 
    map.get(last | first);// O(log(N)) 
    
  2. 排序LinkedHashMap中可以改为创建一个TreeMap实例,因为Map.keySet()返回无序集不清单,让您无法通过它的排序按键映射排序。

    public <K extends Comparable<? super K>, V> Map<K, V> sortByKeys(Map<K, V> map) { 
    return new TreeMap<K, V>(map); 
    } 
    
+0

@Holger请帮我看看这个答案是否正确?首先感谢。 –

+0

当大小超过阈值(负载因素*大小)时,新的'HashMap'实现仍然调整/重新映射表。当每个桶的元素数量低于阈值时,它仍然使用链接列表(不要像类型名称'LinkedList'那样写)。当超过阈值时,将会创建一个平衡树,它首先使用哈希码,因此,具有不同哈希码的桶碰撞被整理出来,不管这些关键字是否可比较。只有真正相同的哈希码,它会尝试使用自然顺序,如果有的话。 – Holger

+0

a)'compareTo'返回零,但'equals'返回'false'(改变'last = new Foo(2)'为'last = new Foo(1)')或者b)而不是“Comparable”,在这种情况下,映射基本上会回退到带有“O(n)”查找的链表。但是,必须强调的是,对于树查找的“O(log(n))”,“n”是桶的数量,对于回退的“O(n)”,“n”是具有相同散列码的对象,不具有'<' or '>'关系,所以'n'不等于'HashMap'的大小。 – Holger