Map接口

本文深入解析Java中的Map接口及其核心实现类,包括HashMap、LinkedHashMap、TreeMap等,探讨它们的特点、应用场景及内部机制,如红黑树和链表结构。同时,文章还对比了HashMap与Hashtable的区别,以及如何正确使用Map的key和value。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Map接口
存储双列数据:存储key–value对(键值对)数据,类似于数学中函数的概念

Map接口的实现类:

  • HashMap,LinkedHashMap(是HashMap的子类)
  • TreeMap
  • Hashtable,Properties(是Hashtable的子类)

实现类之间的关系:

  • HashMap作为Map的主要实现类,线程不安全,效率高,可以存储null的key和value(两个都可以是null)
  • Hashtable作为Map的古老实现类,线程安全,效率低,不可以存储null的key和value(只要有一个是null就不可以),会报空指针异常。基本不使用

注意:和ArrayList一样,即使涉及到了多线程问题,也不会因为Hashtable是安全的,而使用它,而是用Collections工具类的相关方法把HashMap变成线程安全的

 public static void main(String[] args) {
        Map map=new HashMap();
        map.put(null,null);
        map.put(null,123);
    }
  • LinkedHashMap在HashMap的基础上增加了一对指针,指向前一个存放的,和后一个存放的元素,保证在遍历map元素时,可以按照添加的先后顺序实现遍历。对于频繁的遍历操作,效率高于HashMap。如果有频繁的遍历,一般使用此类
  • TreeMap:可以保证根据添加的key–value对进行排序,实现排序遍历,是按照key来排序的,此时考虑key的自然排序或定制排序,底层使用的是红黑树
  • Properties: 常用来处理配置文件,key和value都是String类型

HashMap的底层:
最初的时候是数组加链表(JDK7及之前)
数组+链表+红黑树(JDK8),加红黑树是为了提高效率

Map结构的理解
Map中存储的key-value特点:
value可以重复,key不能重复,并且key还是无序的,key就相当于是用Set存储的,保证无序,不可重复性。
因为key是无序的,key对应value,所以value也不可能有序,value的特点是可重复的,无序的,也没有一种专门的结构去存储这种类型的数据,就泛泛的称作用Collection去存储

事实上,Map中放的是一个一个数据,是一个一个的Entry,是这个Entry当中有两个属性一个叫做key,一个叫做value,实际上调用put方法的时候,put的是一个一个的Entry,添加的其实是Entry对象

因为key没有顺序所以Entry对象也是没有顺序的,key不相同,所以Entry不可重复
Entry的特点:不可重复,无序的,可以理解为用Set承装

Map中的key:无序的,不可重复的,使用Set存储所有的key,到底是什么Set就看Map是什么Map了,如果是HashMap就是HashSet去存key,如果是linkedHashMap就用LinkedHashSet存储

Map中的value:无序的,可重复的,使用Collection存储所有的value,它所在的类不用重写hashCode,重写equals即可。本质上来说它不用重写hashCode的原因:hashCode主要涉及到存的时候效率高一些,找的时候方便一点,value因为封装在Entry当中,找value先去找它的Entry的key

一个键值对key–value构成了一个Entry对象
Map中的Entry:无序的,不可重复的,使用Set存储所有的Entry,不可添加重复数据
key完全有可能是我们自定义的类,为了保证无序性,不可重复性,要求key所在的类要重写equals方法和hashCode方法(这是以HashMap为例的说的,如果是TreeMap就不用管equals方法和hashCode方法了,涉及到自然排序和定制排序了,判断标准就不一样了)
以HashMap为例,containsKey(Object key):是看当前的Map中有没有这个key
判断过程,是先去调用hashCode方法,找到那个位置,再调用equals才知道包不包含这个key
containsValue():用来判断有没有指定的Value

资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 行列式是线性代数的核心概念,在求解线性方程组、分析矩阵特性以及几何计算中都极为关键。本教程将讲解如何用C++实现行列式的计算,重点在于如何输出分数形式的结果。 行列式定义如下:对于n阶方阵A=(a_ij),其行列式由主对角线元素的乘积,按行或列的奇偶性赋予正负号后求和得到,记作det(A)。例如,2×2矩阵的行列式为det(A)=a11×a22-a12×a21,而更高阶矩阵的行列式可通过Laplace展开或Sarrus规则递归计算。 在C++中实现行列式计算时,首先需定义矩阵类或结构体,用二维数组存储矩阵元素,并实现初始化、加法、乘法、转置等操作。为支持分数形式输出,需引入分数类,包含分子和分母两个整数,并提供与整数、浮点数的转换以及加、减、乘、除等运算。C++中可借助std::pair表示分数,或自定义结构体并重载运算符。 计算行列式的函数实现上,3×3及以下矩阵可直接按定义计算,更大矩阵可采用Laplace展开或高斯 - 约旦消元法。Laplace展开是沿某行或列展开,将矩阵分解为多个小矩阵的行列式乘积,再递归计算。在处理分数输出时,需注意避免无限循环和除零错误,如在分数运算前先约简,确保分子分母互质,且所有计算基于整数进行,最后再转为浮点数,以避免浮点数误差。 为提升代码可读性和可维护性,建议采用面向对象编程,将矩阵类和分数类封装,每个类有明确功能和接口,便于后续扩展如矩阵求逆、计算特征值等功能。 总结C++实现行列式计算的关键步骤:一是定义矩阵类和分数类;二是实现矩阵基本操作;三是设计行列式计算函数;四是用分数类处理精确计算;五是编写测试用例验证程序正确性。通过这些步骤,可构建一个高效准确的行列式计算程序,支持分数形式计算,为C++编程和线性代数应用奠定基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值