爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Map接口实现类HashMap,Hashtable和Properties

      首页 知识中心 软件开发 文章详情页

      Map接口实现类HashMap,Hashtable和Properties

      2023-06-01 06:42:03 阅读次数:458

      HashMap,Hashtable,Map

      1. HashMap 小结  535

      1) Map接口的常用实现类HashMap、 Hashtable和Properties.

      2) HashMap是Map接口使用频率最高的实现类。

      3) HashMap是以key-val对的方式来存储数据(HashMap$Node类型)

      4) key不能重复,但是值可以重复,允许使用null键和null值。

      5)如果添加相同的key,则会覆盖原来的key-val ,等同于修改.(key不会替换,val会替换)

      6)与HashSet-样,不保证映射的顺序,因为底层是以hash表的方式来存储的. jdk8的

      hashMap底层数组+链表+红黑树)

      7) HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有

      synchronized

      2. HashMap 底层机制及源码剖析  536

      Map接口实现类HashMap,Hashtable和Properties

      1) (k,v) 是一个Node实现了Map.Entry,查看HashMap的源码可以看到. 

      2) jdk7 .0的hashmap底层实现[数组+链表],jdk8.0底层[数组+链表+红黑树]

      3. HashMap 底层机制及源码剖析  536-537

      ➢扩容机制[和HashSet相同]

      1) HashMap底层维护了Node类型的数组table,默认为null

      2)当创建对象时,将加载因子(loadfactor)初始化为0.75.

      3)当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key和准备加入的key相是否等,如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。

      4)第1次添加,则需要扩容table容量为16,临界值(threshold)为12 (16*0.75)

      5)以后再扩容,则需要扩容table容量为原来的2倍(32),临界值为原来的2倍,即24依次类推

      6)在Java8中,如果条链表的元素个数超过TREEIFY_THRESHOLD(默认是8),并且table的大小>= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)

      代码在com.stulzl.hashmap_source01.包中  537

      HashMap_Source01

      package com.stulzl.hashmap_source01;
      
      import java.util.HashMap;
      
      //HashMap 底层机制及源码剖析  537
      @SuppressWarnings({"all"})
      public class HashMap_Source01 {
          public static void main(String[] args) {
              HashMap map = new HashMap();
              map.put("java", 10);//ok
              map.put("php", 10);//ok
              map.put("java", 20);//替换value
      
              System.out.println("map=" + map);//map={java=20, php=10}
              /*解读HashMap的源码+图解
              1. 执行构造器 new HashMap()
                 初始化加载因子 loadfactor = 0.75
                 HashMap$Node[] table = null
              2. 执行put 调用 hash方法,计算 key的 hash值 (h = key.hashCode()) ^ (h >>> 16)
                  public V put(K key, V value) {//K = "java" value = 10
                      return putVal(hash(key), key, value, false, true);
                  }
               3. 执行 putVal
               final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                         boolean evict) {
                      Node[] tab; Node p; int n, i;//辅助变量
                      //如果底层的table 数组为null, 或者 length =0 , 就扩容到16
                      if ((tab = table) == null || (n = tab.length) == 0)
                          n = (tab = resize()).length;
                      //取出hash值对应的table的索引位置的Node, 如果为null, 就直接把加入的k-v
                      //, 创建成一个 Node ,加入该位置即可
                      if ((p = tab[i = (n - 1) & hash]) == null)
                          tab[i] = newNode(hash, key, value, null);
                      else {
                          Node e; K k;//辅助变量
                      // 如果table的索引位置的key的hash相同和新的key的hash值相同,
                       // 并 满足(table现有的结点的key和准备添加的key是同一个对象  || equals返回真)
                       // 就认为不能加入新的k-v
                          if (p.hash == hash &&
                              ((k = p.key) == key || (key != null && key.equals(k))))
                              e = p;
                          else if (p instanceof TreeNode)//如果当前的table的已有的Node 是红黑树,就按照红黑树的方式处理
                              e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
                          else {
                              //如果找到的结点,后面是链表,就循环比较
                              for (int binCount = 0; ; ++binCount) {//死循环
                                  if ((e = p.next) == null) {//如果整个链表,没有和他相同,就加到该链表的最后
                                      p.next = newNode(hash, key, value, null);
                                      //加入后,判断当前链表的个数,是否已经到8个,到8个,后
                                      //就调用 treeifyBin 方法进行红黑树的转换
                                      if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                          treeifyBin(tab, hash);
                                      break;
                                  }
                                  if (e.hash == hash && //如果在循环比较过程中,发现有相同,就break,就只是替换value
                                      ((k = e.key) == key || (key != null && key.equals(k))))
                                      break;
                                  p = e;
                              }
                          }
                          if (e != null) { // existing mapping for key
                              V oldValue = e.value;
                              if (!onlyIfAbsent || oldValue == null)
                                  e.value = value; //替换,key对应value
                              afterNodeAccess(e);
                              return oldValue;
                          }
                      }
                      ++modCount;//每增加一个Node ,就size++
                      if (++size > threshold[12-24-48])//如size > 临界值,就扩容
                          resize();
                      afterNodeInsertion(evict);
                      return null;
                  }
      
                    5. 关于树化(转成红黑树)
                    //如果table 为null ,或者大小还没有到 64,暂时不树化,而是进行扩容.
                    //否则才会真正的树化 -> 剪枝
                    final void treeifyBin(Node[] tab, int hash) {
                      int n, index; Node e;
                      if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
                          resize();
      
                  }
               */
          }
      }

      4. 模拟HashMap触发扩容、树化情况,并Debug验证.538

      代码在com.stulzl.hashmap_source02.包中

      HashMap_Source02

      package com.stulzl.hashmap_source02;
      
      import java.util.HashMap;
      import java.util.Objects;
      
      // 模拟HashMap触发扩容、树化情况,并Debug验证.538
      @SuppressWarnings({"all"})
      public class HashMap_Source02 {
          public static void main(String[] args) {
              HashMap hashMap = new HashMap();
              for (int i = 1; i <=12; i++) {
                  hashMap.put(new A(i),"hello");
              }
      
              //12 个k-v,因为重写了hash值方法,所以hash值一样,所有的数据都挂载到一个链表上
              System.out.println("hashMap="+hashMap);
          }
      }
      class A{
          private int num;
      
          public A(int num) {
              this.num = num;
          }
      
          @Override
          public String toString() {
              return "\nA{" +
                      "num=" + num +
                      '}';
          }
      
          //重写hash值  使所有的A对象的hashCode都是100
          @Override
          public int hashCode() {
              return 100;
          }
      }

      5. HashTable 的基本介绍

      1)存放的元素是键值对:即K-V

      2) hashtable的键和值都不能为null, 否则会抛出NullPointerException

      3) hashTable使用方法基本上和HashMap一样

      4) hashTable是线程安全的(synchronized), hashMap是线程不安全的

      5.1 HashTable的基本介绍应用案例  539-540

      代码在com.stulzl.hashtable.包中

      Hashtable_Exercise01
      package com.stulzl.hashtable;
      
      import java.util.Hashtable;
      
      //HashTable的基本介绍应用案例  539-540
      @SuppressWarnings({"all"})
      public class Hashtable_Exercise01 {
          public static void main(String[] args) {
              Hashtable table = new Hashtable();
              table.put("john", 100); //ok
      
              //hashtable的键和值都不能为null, 否则会抛出NullPointerException
              //table.put(null, 100); //异常 NullPointerException
              //table.put("john", null);//异常 NullPointerException
              table.put("lucy", 100);//ok
              table.put("lic", 100);//ok
              table.put("lic", 88);//替换
              table.put("hello1", 1);
              table.put("hello2", 1);
              table.put("hello3", 1);
              table.put("hello4", 1);
              table.put("hello5", 1);
              table.put("hello6", 1);
              System.out.println(table);
      
              //简单说明一下Hashtable的底层
              //1. 底层有数组 Hashtable$Entry[] 初始化大小为 11
              //2. 临界值 threshold 8 = 11 * 0.75
              //3. 扩容: 按照自己的扩容机制来进行即可.
              //4. 执行 方法 addEntry(hash, key, value, index); 添加K-V 封装到Entry
              //5. 当 if (count >= threshold) 满足时,就进行扩容
              //6. 按照 int newCapacity = (oldCapacity << 1) + 1; 即(*2+1)的大小扩容.
          }
      }

      6.  Hashtable 和 HashMap 对比 540

      Map接口实现类HashMap,Hashtable和Properties

      7. Map 接口实现类-Properties  541

      7.1 基本介绍

      1. Properties类继承自Hashtable类并且实现了 Map接口,也是使用一种键值对的形式来保存数据。

      2.他的使用特点和Hashtable类似

      3. Properties 还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改

      4.说明:工作后xxx.properties 文件通常作为配置文件,这个知识点在IO流举例,有兴趣可先看文章

      7.2 Properties基本使用案例  541

      代码在com.stulzl.properties.包中

      Properties_
      package com.stulzl.properties;
      
      import java.util.Properties;
      
      //Properties基本使用案例  541
      @SuppressWarnings({"all"})
      public class Properties_ {
          public static void main(String[] args) {
              //解读
              //1. Properties 继承  Hashtable
              //2. 可以通过 k-v 存放数据,当然key 和 value 不能为 null
              //增加
              Properties properties = new Properties();
              //properties.put(null, "abc");//抛出 空指针异常
              //properties.put("abc", null); //抛出 空指针异常
              properties.put("john", 100);//k-v
              properties.put("lucy", 100);
              properties.put("lucy", 200);
              properties.put("lic", 100);
              properties.put("lic", 88);//如果有相同的key , value被替换
              System.out.println("properties="+properties);
      
              //通过k 获取对应值
              System.out.println(properties.get("lic"));//88
      
              //删除
              //properties.remove("lic");
              System.out.println("properties="+properties);
      
              //修改
              properties.put("john","约翰");
              System.out.println("properties="+properties);
      
              //查
              System.out.println(properties.get("lic"));//88
              System.out.println(properties.getProperty("lucy"));//如果value部位String类型返回null
          }
      }

      8. 总结-开发中如何选择集合实现类(记住)   542

      在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行

      选择,分析如下:

      1)先判断存储的类型(一组对象[单列]或组键值对[双列)

      2)一组对象[单列]: Collection接口

      允许重复: List

      增删多: LinkedList [底层维护了一个双向链表]

      改查多: ArrayList [底层维护Object类型的可变数组]

      不允许重复: Set

      无序HashSet [底层是HashMap,维护了一一个哈希表即(数组+链表+红黑树)]

      排序: TreeSet

      插入和取出顺序一致: LinkedHashSet , 维护数组+双向链表

      3)一组健值对[双列]: Map

      键无序: HashMap [底层是:哈希表jdk7: 数组+链表,jdk8: 数组+链表+红黑树]

      键排序: TreeMap

      键插入和取出顺序一致: LinkedHashMap

      读取文件Properties

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.51cto.com/u_15784725/6290359,作者:进击的菜鸟子,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:Java常用工具类方法(下)

      下一篇:线程的生命周期,同步和锁

      相关文章

      2025-05-14 10:03:05

      30天拿下Rust之HashMap

      HashMap,被称为哈希表或散列表,是一种可以存储键值对的数据结构。它使用哈希函数将键映射到存储位置,以便可以快速检索和更新元素。

      2025-05-14 10:03:05
      HashMap , 使用 , 哈希 , 引用 , 方法 , 遍历 , 键值
      2025-05-14 09:51:21

      java 判断map为null或者空

      java 判断map为null或者空

      2025-05-14 09:51:21
      Java , Map , null , 方法 , 是否 , 检查 , 示例
      2025-05-13 09:53:23

      Java交换map的key和value值

      在Java中,我们都知道直接交换Map的key和value是不被允许的,因为Map的接口设计是基于key-value对的,其中key是唯一的,并且是不可变的(在HashMap等常见的实现中,虽然key的引用是不可变的,但key对象本身如果是可变的,它的内容是可以变化的,但这样做可能会导致不正确的行为或异常)。

      2025-05-13 09:53:23
      key , List , Map , null , value , 映射 , 键值
      2025-05-13 09:50:17

      java实现3. 无重复字符的最长子串

      给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。 

      2025-05-13 09:50:17
      HashMap , 复杂度 , 字符 , 字符串 , 数组 , 算法
      2025-04-15 09:20:33

      初学Java,集合类概述(二十五)

      初学Java,集合类概述(二十五)

      2025-04-15 09:20:33
      Collection , Map , 键值 , 集合
      2025-04-15 09:19:55

      初学Java,Hashtable,HashMap,LinkedHashMap和Properties(三十一)

      初学Java,Hashtable,HashMap,LinkedHashMap和Properties(三十一)

      2025-04-15 09:19:55
      HashMap , Hashtable , Key , Map , null , 属性 , 文件
      2025-04-11 07:11:40

      java.lang.IllegalStateException: Duplicate key异常解决

      java.lang.IllegalStateException: Duplicate key异常解决

      2025-04-11 07:11:40
      key , Map , stream , 数据
      2025-03-28 07:42:34

      for...in、for...of和其他循环的区别

      for...in、for...of和其他循环的区别

      2025-03-28 07:42:34
      Map , 对象 , 属性 , 数组 , 枚举 , 遍历
      2025-03-28 07:41:55

      javaScript Array.Map的使用

      javaScript Array.Map的使用

      2025-03-28 07:41:55
      item , map , Map , 元素 , 数组
      2025-03-27 10:12:02

      【Java】使用集合接口的时候应该使用通用类型代替具体的实现类型

      【Java】使用集合接口的时候应该使用通用类型代替具体的实现类型

      2025-03-27 10:12:02
      HashMap , Java , LinkedList , new , 实例
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5256587

      查看更多

      最新文章

      java 判断map为null或者空

      2025-05-14 09:51:21

      Java交换map的key和value值

      2025-05-13 09:53:23

      初学Java,集合类概述(二十五)

      2025-04-15 09:20:33

      初学Java,Hashtable,HashMap,LinkedHashMap和Properties(三十一)

      2025-04-15 09:19:55

      javaScript Array.Map的使用

      2025-03-28 07:41:55

      【Java】使用集合接口的时候应该使用通用类型代替具体的实现类型

      2025-03-27 10:12:02

      查看更多

      热门文章

      Java的HashMap与LinkedHashMap异同

      2023-04-17 09:41:12

      Java entrySet之Map.Entry

      2023-04-11 10:15:33

      java的hashmap,如果确定只装载100个元素,new HashMap(?)多少是最佳的,why?

      2023-02-27 09:40:31

      Java HashMap源码浅析

      2023-03-10 03:11:39

      Java集合之HashMap知多少

      2023-04-06 09:56:07

      Map接口和常用方法

      2023-05-29 10:47:06

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      Java源码解读-HashMap(基于JDK8)

      Java集合之HashMap知多少

      Java高级之1.7版本JDK中的HashMap的indexFor()方法

      Map接口和常用方法

      Map 接口和常用方法

      HashMap原理详解及常用API介绍

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号