Java的TreeMap和HashMap的介绍和使用

Java的TreeMap和HashMap的介绍和使用1 TreeMap 的介绍和使用第 1 部分 TreeMap 介绍 TreeMap 简介 TreeMap 是一个有序的 key value 集合 它是通过红黑树实现的 TreeMap nbsp 继承于 AbstractMap 所以它是一个 Map 即一个 key value 集合 TreeMap 实现了 NavigableMap 接口 意味着它支持一系列的导航方法 比如返回有序的 key 集合

1. TreeMap的介绍和使用

第1部分 TreeMap介绍

TreeMap 简介

TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。
TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
TreeMap 实现了Cloneable接口,意味着它能被克隆
TreeMap 实现了java.io.Serializable接口,意味着它支持序列化



TreeMap基于红黑树(Red-Black tree)实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
另外,TreeMap是非同步的。 它的iterator 方法返回的迭代器是fail-fastl的。

TreeMap的构造函数

// 默认构造函数。使用该构造函数,TreeMap中的元素按照自然排序进行排列。 TreeMap() // 创建的TreeMap包含Map TreeMap(Map 
    copyFrom) // 指定Tree的比较器 TreeMap(Comparator 
    comparator) // 创建的TreeSet包含copyFrom TreeMap(SortedMap 
   
     copyFrom) 
   



TreeMap的API

Map.Entry 
   
     ceilingEntry(K key) 返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null。 K ceilingKey(K key) 返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。 void clear() 从此映射中移除所有映射关系。 Object clone() 返回此 TreeMap 实例的浅表副本。 Comparator 
     comparator() 返回对此映射中的键进行排序的比较器;如果此映射使用键的自然顺序,则返回 null。 boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。 boolean containsValue(Object value) 如果此映射为指定值映射一个或多个键,则返回 true。 NavigableSet 
    
      descendingKeySet() 返回此映射中所包含键的逆序 NavigableSet 视图。 NavigableMap 
     
       descendingMap() 返回此映射中所包含映射关系的逆序视图。 Set 
      
        > entrySet() 返回此映射中包含的映射关系的 Set 视图。 Map.Entry 
       
         firstEntry() 返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。 K firstKey() 返回此映射中当前第一个(最低)键。 Map.Entry 
        
          floorEntry(K key) 返回一个键-值映射关系,它与小于等于给定键的最大键关联;如果不存在这样的键,则返回 null。 K floorKey(K key) 返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。 V get(Object key) 返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null。 SortedMap 
         
           headMap(K toKey) 返回此映射的部分视图,其键值严格小于 toKey。 NavigableMap 
          
            headMap(K toKey, boolean inclusive) 返回此映射的部分视图,其键小于(或等于,如果 inclusive 为 true)toKey。 Map.Entry 
           
             higherEntry(K key) 返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null。 K higherKey(K key) 返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。 Set 
            
              keySet() 返回此映射包含的键的 Set 视图。 Map.Entry 
             
               lastEntry() 返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。 K lastKey() 返回映射中当前最后一个(最高)键。 Map.Entry 
              
                lowerEntry(K key) 返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。 K lowerKey(K key) 返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。 NavigableSet 
               
                 navigableKeySet() 返回此映射中所包含键的 NavigableSet 视图。 Map.Entry 
                
                  pollFirstEntry() 移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。 Map.Entry 
                 
                   pollLastEntry() 移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。 V put(K key, V value) 将指定值与此映射中的指定键进行关联。 void putAll(Map 
                   map) 将指定映射中的所有映射关系复制到此映射中。 V remove(Object key) 如果此 TreeMap 中存在该键的映射关系,则将其删除。 int size() 返回此映射中的键-值映射关系数。 NavigableMap 
                  
                    subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) 返回此映射的部分视图,其键的范围从 fromKey 到 toKey。 SortedMap 
                   
                     subMap(K fromKey, K toKey) 返回此映射的部分视图,其键值的范围从 fromKey(包括)到 toKey(不包括)。 SortedMap 
                    
                      tailMap(K fromKey) 返回此映射的部分视图,其键大于等于 fromKey。 NavigableMap 
                     
                       tailMap(K fromKey, boolean inclusive) 返回此映射的部分视图,其键大于(或等于,如果 inclusive 为 true)fromKey。 Collection 
                      
                        values() 返回此映射包含的值的 Collection 视图。 
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
   



第2部分 TreeMap数据结构

TreeMap的继承关系

java.lang.Object java.util.AbstractMap 
   
     java.util.TreeMap 
    
      public class TreeMap 
     
       extends AbstractMap 
      
        implements NavigableMap 
       
         , Cloneable, java.io.Serializable {} 
        
       
      
     
   



TreeMap与Map关系如下图:

Java的TreeMap和HashMap的介绍和使用

从图中可以看出:
(01) TreeMap实现继承于AbstractMap,并且实现了NavigableMap接口。
(02) TreeMap的本质是R-B Tree(红黑树),它包含几个重要的成员变量: rootsizecomparator
  root 是红黑数的根节点。它是Entry类型,Entry是红黑数的节点,它包含了红黑数的6个基本组成成分:key(键)、value(值)、left(左孩子)、right(右孩子)、parent(父节点)、color(颜色)。Entry节点根据key进行排序,Entry节点包含的内容为value。 
  红黑数排序时,根据Entry中的key进行排序;Entry中的key比较大小是根据比较器comparator来进行判断的。
  size是红黑数中节点的个数。




关于红黑数的具体算法,请参考”红黑树(一) 原理和算法详细介绍“。

第3部分 TreeMap遍历方式

3.1 遍历TreeMap的键值对

第一步:根据entrySet()获取TreeMap的“键值对”的Set集合。
第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象 // map中的key是String类型,value是Integer类型 Integer integ = null; Iterator iter = map.entrySet().iterator(); while(iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); // 获取key key = (String)entry.getKey(); // 获取value integ = (Integer)entry.getValue(); }



3.2 遍历TreeMap的键

第一步:根据keySet()获取TreeMap的“键”的Set集合。
第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象 // map中的key是String类型,value是Integer类型 String key = null; Integer integ = null; Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { // 获取key key = (String)iter.next(); // 根据key,获取value integ = (Integer)map.get(key); } 



3.3 遍历TreeMap的值

第一步:根据value()获取TreeMap的“值”的集合。
第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象 // map中的key是String类型,value是Integer类型 Integer value = null; Collection c = map.values(); Iterator iter= c.iterator(); while (iter.hasNext()) { value = (Integer)iter.next(); }



以上转自:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3310928



2. HashMap的介绍和使用

HashMap简介 
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 
HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。 
HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。 
HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。 
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。




HashMap的继承关系 
Java的TreeMap和HashMap的介绍和使用

HashMap与Map关系如下图: 
Java的TreeMap和HashMap的介绍和使用 
HashMap的构造函数 

HashMap共有4个构造函数,如下:

复制代码 代码如下:

// 默认构造函数。 
HashMap() 
// 指定“容量大小”的构造函数 
HashMap(int capacity) 
// 指定“容量大小”和“加载因子”的构造函数 
HashMap(int capacity, float loadFactor) 
// 包含“子Map”的构造函数 
HashMap(Map
map)






HashMap的API

复制代码 代码如下:

void                 clear() 
Object               clone() 
boolean              containsKey(Object key) 
boolean              containsValue(Object value) 
Set

>     entrySet() 

V                    get(Object key) 
boolean              isEmpty() 
Set

               keySet() 

V                    put(K key, V value) 
void                 putAll(Map
map) 
V                    remove(Object key) 
int                  size() 
Collection

        values()
















以上转自:https://www.cnblogs.com/mkfywj/p/5543600.html#top



3. HashMap,LinkedHashMap,TreeMap的有序性

HashMap 是将 Key 做 Hash 算法,然后将 Hash 值映射到内存地址,直接取得 Key 所对应的数据。在 HashMap 中,底层数据结构使用的是数组,所谓的内存地址即数组的下标索引。HashMap 的高性能需要保证以下几点:


Hash 算法必须是高效的;
Hash 值到内存地址 (数组索引) 的算法是快速的;
根据内存地址 (数组索引) 可以直接取得对应的值。
HashMap 实际上是一个链表的数组。基于 HashMap 的链表方式实现机制,只要 HashCode() 和 Hash() 方法实现得足够好,能够尽可能地减少冲突的产生,那么对 HashMap 的操作几乎等价于对数组的随机访问操作,具有很好的性能。但是,如果 HashCode() 或者 Hash() 方法实现较差,在大量冲突产生的情况下,HashMap 事实上就退化为几个链表,对 HashMap 的操作等价于遍历链表,此时性能很差。




HashMap 的一个功能缺点是它的无序性,被存入到 HashMap 中的元素,在遍历 HashMap 时,其输出是无序的。如果希望元素保持输入的顺序,可以使用 LinkedHashMap 替代。


LinkedHashMap 继承自 HashMap,具有高效性,同时在 HashMap 的基础上,又在内部增加了一个链表,用以存放元素的顺序。


HashMap 通过 hash 算法可以最快速地进行 Put() 和 Get() 操作。TreeMap 则提供了一种完全不同的 Map 实现。从功能上讲,TreeMap 有着比 HashMap 更为强大的功能,它实现了 SortedMap 接口,这意味着它可以对元素进行排序。TreeMap 的性能略微低于 HashMap。如果在开发中需要对元素进行排序,那么使用 HashMap 便无法实现这种功能,使用 TreeMap 的迭代输出将会以元素顺序进行。LinkedHashMap 是基于元素进入集合的顺序或者被访问的先后顺序排序,TreeMap 则是基于元素的固有顺序 (由 Comparator 或者 Comparable 确定)。


LinkedHashMap 是根据元素增加或者访问的先后顺序进行排序,而 TreeMap 则根据元素的 Key 进行排序。



测试代码:

package mapKeySet; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; / * 2015年4月9日下午3:33:44 * @version 1.0 */ public class KeySetTest { public static void main(String[] args) { Map 
    
      map = new HashMap 
     
       (); map.put("a", "1"); map.put("b", "2"); map.put("c", "3"); map.put("d", "4"); System.out.print("HashMap:"); for(String key : map.keySet()) { System.out.print(map.get(key) + " "); } Map 
      
        linkedMap = new LinkedHashMap 
       
         (); linkedMap.put("a", "1"); linkedMap.put("b", "2"); linkedMap.put("c", "3"); linkedMap.put("d", "4"); System.out.print("LinkedHashMap:"); for(String key : linkedMap.keySet()) { System.out.print(linkedMap.get(key) + " "); } Map 
        
          treeMap = new TreeMap 
         
           (); treeMap.put("a", "1"); treeMap.put("b", "2"); treeMap.put("c", "3"); treeMap.put("d", "4"); System.out.print("TreeMap:"); for(String key : treeMap.keySet()) { System.out.print(treeMap.get(key) + " "); } } } 
          
         
        
       
      
    



输出结果:

HashMap:4 2 3 1 LinkedHashMap:1 2 3 4 TreeMap:1 2 3 4



以上转自:http://blog.csdn.net/zhuhao717/article/details/47444763



4. 二维HashMap

声明:

HashMap 
    
      > map1; 
    

添加元素:

HashMap 
    
      temp_hash=new HashMap 
     
       (); temp_hash.put(string1, 1); map1.put(string2,temp_hash); 
      
    

遍历:

申请一个迭代器:

Iterator 
    
      it1=map1.keySet().iterator(); 
    

访问:

while(it_verb.hasNext()){ String temp=it.next(); HashMap 
    
      temp_map=verb_map.get(temp); } 
    



以上参考:http://blog.csdn.net/sdcyzjq/article/details/6609137



// 代码实现 import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; public class TestTreeMap { public static void main(String[] args) { // TODO Auto-generated method stub TreeMap 
    
      map = new TreeMap<>(); map.put(3, "aa"); map.put(2, "bb"); map.put(4, "cc"); map.put(1, "dd"); map.put(5, "dd"); map.put(6, "ee"); System.out.print("original: "); Iterator it = map.entrySet().iterator(); while(it.hasNext()) { Map.Entry e = (Map.Entry)it.next(); int key = (Integer)e.getKey(); String val = (String)e.getValue(); System.out.print(key + " " + val + (it.hasNext() ? ", " : ".")); } System.out.println(); System.out.println("-------------------------------"); map.remove(6); System.out.print("after remove: "); it = map.entrySet().iterator(); while(it.hasNext()) { Map.Entry e = (Map.Entry)it.next(); int key = (Integer)e.getKey(); String val = (String)e.getValue(); System.out.print(key + " " + val + (it.hasNext() ? ", " : ".")); } System.out.println(); System.out.println("-------------------------------"); System.out.println(3 + "'s val: " + map.get(3)); System.out.println(3 + "'s higherKey: " + map.higherKey(3)); Map.Entry tmp1 = map.higherEntry(3); System.out.println(3 + "'s higherEntry: " + (Integer)tmp1.getKey() + " " + (String)tmp1.getValue()); System.out.println(3 + "'s lowerKey: " + map.lowerKey(3)); Map.Entry tmp2 = map.lowerEntry(3); System.out.println(3 + "'s lowerEntry: " + (Integer)tmp2.getKey() + " " + (String)tmp2.getValue()); System.out.println("firstKey: " + map.firstKey() + ", " + "lastKey: " + map.lastKey()); System.out.println(); TestUserDefined(); TestTwoDimensional(); } private static class Node implements Comparable 
     
       { int a, b; public Node(int a, int b) { this.a = a; this.b = b; } @Override public int compareTo(Node o) { // TODO Auto-generated method stub if(this.a == o.a) { return (this.b < o.b) ? 1 : -1; } else { return (this.a > o.a) ? 1 : -1; } } public String toString() { return "{ " + this.a + "," + this.b + " }"; } } private static class mycmp implements Comparator 
      
        { @Override public int compare(Node o1, Node o2) { // TODO Auto-generated method stub if(o1.a == o2.a) { return o1.b - o2.b; } return o2.a - o1.a; } } private static void TestUserDefined() { // By Comparable接口 TreeMap 
       
         map1 = new TreeMap<>(); map1.put(new Node(3, 2), "aa"); map1.put(new Node(3, 4), "bb"); map1.put(new Node(5, 8), "cc"); map1.put(new Node(5, 7), "dd"); map1.put(new Node(6, 9), "ee"); Iterator it1 = map1.entrySet().iterator(); while(it1.hasNext()) { Map.Entry e = (Map.Entry)it1.next(); System.out.println((Node)e.getKey() + ": " + (String)e.getValue()); } System.out.println(); System.out.println("-------------------------------"); System.out.println(); // By Comparator接口 TreeMap 
        
          map2 = new TreeMap<>(new mycmp()); map2.put(new Node(3, 2), "aa"); map2.put(new Node(3, 4), "bb"); map2.put(new Node(5, 8), "cc"); map2.put(new Node(5, 7), "dd"); map2.put(new Node(6, 9), "ee"); Iterator it2 = map2.entrySet().iterator(); while(it2.hasNext()) { Map.Entry e = (Map.Entry)it2.next(); System.out.println((Node)e.getKey() + ": " + (String)e.getValue()); } System.out.println(); } private static void TestTwoDimensional() { TreeMap 
         
           > mmp = new TreeMap<>(); TreeMap 
          
            tmpMap = new TreeMap<>(); tmpMap.put(1, "a"); tmpMap.put(3, "b"); tmpMap.put(2, "c"); mmp.put(1, tmpMap); mmp.put(3, tmpMap); mmp.put(2, tmpMap); Iterator it = mmp.entrySet().iterator(); while(it.hasNext()) { Map.Entry e = (Map.Entry)it.next(); int key = (Integer)e.getKey(); tmpMap = (TreeMap 
           
             )e.getValue(); System.out.print(key + "-> { "); Iterator tmpIt = tmpMap.entrySet().iterator(); while(tmpIt.hasNext()) { Map.Entry tmpe = (Map.Entry)tmpIt.next(); int tmpkey = (Integer)tmpe.getKey(); String tmpval = (String)tmpe.getValue(); System.out.print(tmpkey + " " + tmpval + (tmpIt.hasNext() ? ", " : "")); } System.out.println(" }"); } } } 
            
           
          
         
        
       
      
    



继续加油~



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218891.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午11:13
下一篇 2026年3月17日 下午11:14


相关推荐

  • 玩转xss

    玩转xss0x00前言很多人现在都没懂xss为什么这么鸡肋的漏洞能排到owasp前十名,xss做多也就拿来做个弹窗和打cookie,然后进入后台,感觉没啥意义,还不如弱口令来得实在。那么我们就先

    2021年12月11日
    108
  • NTKO使用说明

    NTKO使用说明1 文件更新及布署 a 增加文件 Poral Ajax SheetInfo ashx 主要用于获取流程表单的信息 可自己扩展 b Portal Office 文件夹完整替换 测试环境 Office1 为原来的文件夹 c 增加 JS 文件 NTKO 套用模块 印章的方法 Portal WFRes Scripts MVCSheet SheetOfficeN jsd 修改 Sheet

    2026年3月16日
    2
  • Java实现将数字转为大写汉字

    Java实现将数字转为大写汉字

    2022年3月6日
    52
  • css两端对齐

    css两端对齐两端对齐在导航 Nav 的制作中非常常用 例子例如下面这个例子 在导航栏中 我们希望左边的 nav 文字左端对齐 右边的 button 有段对齐 并且导航栏部分居中 和上边 banner 中的文字 以及下边的内容居中对齐 概念 flex 弹性盒模型 flex 作为强大的弹性布局方式 可以 hold 住大部分的布局效果 当然也包括两端对齐 可以使用主轴对齐 justify content 的两端对齐属性 space between display flex 应用 flex 布局 justify content space be

    2026年3月20日
    2
  • hdfs读写文件过程

    hdfs读写文件过程hdfs读写文件过程

    2022年4月23日
    45
  • Kimi长思考模型API正式上线,多模态推理能力引关注

    Kimi长思考模型API正式上线,多模态推理能力引关注

    2026年3月12日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号