首页 > 其他分享 >问题驱动-Map数据结构

问题驱动-Map数据结构

时间:2023-07-02 13:07:18浏览次数:35  
标签:Map HashMap map TreeMap Value Key 驱动 数据结构

1、 引言

Map是Java中常用的数据结构,它提供了一种键值对的存储方式,可以根据键来快速访问值。在本篇文章中,我将学习Java中的Map数据结构

从至少以下几个方面阐述,什么是map、使用Map有什么好处、Map的底层原理、map中的key和value分别是什么、以及Map的Key值为什么不能重复、Map中的key值和Hash有什么关系。

以及对HashMap、TreeMap和LinkedHashMap三种常用的Map实现类进行了解。我将逐步解析它们的初始化、添加和获取元素、遍历和删除元素等功能。

2、问题

什么是Map

Map是Java中的一个接口,它代表了一种键值对的映射关系。它允许我们通过Key来访问Value。在Map中,每个Key都是唯一的,而且与该Key对应的Value是一一对应的关系。

使用Map的好处

使用Map有很多好处,以下是其中几个重要的好处:

  1. 快速访问:通过给定的Key,可以快速地访问对应的Value,无需遍历整个集合。
  2. 灵活性:Map不仅可以存储基本数据类型的值,还可以存储自定义对象作为Value,这使得它非常灵活。
  3. 动态增长:Map的大小可根据需要动态增长,不需要事先指定容量。
  4. 数据分类:Map可以用于对数据进行分类、分组和存储,为后续的检索和处理提供了便利。

Map的底层原理

在Java中,常用的Map实现类有HashMap、TreeMap和LinkedHashMap。这些实现类在底层的数据组织方式和查找算法上略有不同。

HashMap使用散列表(Hash Table)作为底层数据结构,它通过把Key的Hash值映射到一个数组索引上,并使用链地址法解决Hash冲突。

TreeMap使用红黑树(Red-Black Tree)作为底层数据结构,它会对Key进行排序,并且可以提供有序的遍历。

LinkedHashMap继承自HashMap,它在HashMap的基础上通过维护一个双向链表来保证插入顺序或访问顺序。

根据实际情况选择不同的Map实现类,可以根据需求来平衡时间复杂度和空间复杂度。

下面将会了解这几个实现类的一些方法。

Key和Value的含义

在Map中,Key用于唯一标识一个键值对,它相当于数据的索引。Value则是与Key相关联的数据。对于同一个Key,只能有一个对应的Value,但是不同的Key可以对应不同的Value。

例如,我们可以创建一个Map,将每个人的名字作为Key,将他们的年龄作为Value。通过Key,我们可以快速地查找到对应的年龄。

Key值为什么不能重复

Map中要求每个Key都是唯一的,这是因为Map需要通过Key来定位和访问Value。如果出现多个相同的Key,Map无法确定应该返回哪个Value。

当我们使用put方法向Map中添加键值对时,如果Key已经存在,新的Value将会覆盖旧的Value。因此,Key的唯一性保证了在Map中定位Value的准确性。

Key值和Hash的关系

Java中的HashMap和LinkedHashMap是通过计算Key的Hash值来确定Key在底层数组中的位置的。

在HashMap中,当我们向其中插入一个键值对时,HashMap会首先通过Key的hashCode()方法计算Key的哈希值。然后,HashMap会根据哈希值对数组的长度取模,得到Key在底层数组中的索引位置。如果有多个Key的哈希值映射到同一个索引位置,则HashMap会使用链表或红黑树来处理冲突。

而在LinkedHashMap中,它在HashMap的基础上通过维护一个双向链表来保证插入顺序或访问顺序。HashMap中的Key与链表节点相互关联,实现了按照插入顺序或访问顺序迭代Map的键值对。

由此可见,Hash在Map中起到了定位Key的作用,通过计算Key的哈希值,可以快速地定位到Key在底层数组中的位置,从而提高了查找效率。同时,Hash值的唯一性也保证了Key在Map中的唯一性。

由于Hash值是通过哈希函数计算得出的,存在一定的碰撞概率。因此,在使用自定义对象作为Key时,我们需要重写hashCode()方法来确保生成的Hash值能够准确地表示对象的唯一性,同时也要重写equals()方法来处理碰撞冲突时的比较逻辑。这样可以保证不同的Key对象即使在Hash值相同的情况下,也可以正确地进行比较和查找。 

3. HashMap

3.1 初始化HashMap

在Java中,我们可以使用HashMap类来创建一个HashMap对象。下面是一些常见的初始化方法:

  • 使用默认构造函数:HashMap<String, Integer> map = new HashMap<>();
  • 指定初始容量:HashMap<String, Integer> map = new HashMap<>(16);
  • 指定初始容量和加载因子:HashMap<String, Integer> map = new HashMap<>(16, 0.75f);

3.2 添加和获取元素

向HashMap中添加元素时,我们需要使用put()方法,并提供键和值。下面是一个示例:

HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 5);
map.put("banana", 10);
map.put("orange", 8);

获取HashMap中的元素可以使用get()方法,并提供键。下面是一个示例:

int appleCount = map.get("apple");
System.out.println("苹果数量:" + appleCount);

3.3 遍历HashMap

遍历HashMap可以使用多种方式,比如使用迭代器、for-each循环或使用Java 8的Lambda表达式。下面是一个使用迭代器遍历HashMap的示例:

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
    Map.Entry<String, Integer> entry = iterator.next();
    System.out.println("水果:" + entry.getKey() + ",数量:" + entry.getValue());
}

3.4 删除元素

从HashMap中删除元素可以使用remove()方法,并提供键。下面是一个示例:

map.remove("banana");

4. TreeMap

4.1 初始化TreeMap

与HashMap类似,我们可以使用TreeMap类来创建一个TreeMap对象。下面是一些常见的初始化方法:

  • 使用默认构造函数:TreeMap<String, Integer> map = new TreeMap<>();
  • 使用Comparator初始化:TreeMap<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());

4.2 添加和获取元素

添加和获取元素的方式与HashMap类似,使用put()方法添加元素,使用get()方法获取元素。

map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);

int value = map.get("apple");
System.out.println(value);  // 输出:1

4.3 遍历TreeMap

遍历TreeMap的方法与HashMap类似,可以使用迭代器、for-each循环或Lambda表达式。

以下是使用for-each循环遍历TreeMap的例子:

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    int value = entry.getValue();
    System.out.println(key + " : " + value);
}

4.4 删除元素

从TreeMap中删除元素的方式与HashMap类似,使用remove()方法。

map.remove("banana");

5. LinkedHashMap

5.1 初始化LinkedHashMap

LinkedHashMap是一个有序的Map实现类,保留了元素的插入顺序。初始化方式与HashMap类似。

使用默认构造函数:

LinkedHashMap<String, Integer> map = new LinkedHashMap<>();

5.2 添加和获取元素

添加和获取元素的方式与HashMap类似,使用put()方法添加元素,使用get()方法获取元素。

map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);

int value = map.get("apple");
System.out.println(value);  // 输出:1

5.3 遍历LinkedHashMap

遍历LinkedHashMap的方法与HashMap类似,可以使用迭代器、for-each循环或Lambda表达式。

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    int value = entry.getValue();
    System.out.println(key + " : " + value);
}

5.4 删除元素

从LinkedHashMap中删除元素的方式与HashMap类似,使用remove()方法。

6、总结

我们可以看到HashMap、TreeMap和LinkedHashMap都是非常有用和灵活的Map实现类,每种都适用于不同的使用场景。当我们需要一个无序、高效的Map时,可以选择HashMap;当我们需要一个有序的Map时,可以选择TreeMap;而当我们需要一个保留插入顺序、支持特殊操作的Map时,可以选择LinkedHashMap。

因此,当我们需要使用Map数据结构时,我们可以根据具体需求选择合适的数据结构来解决问题。

标签:Map,HashMap,map,TreeMap,Value,Key,驱动,数据结构
From: https://blog.51cto.com/u_15843649/6604423

相关文章

  • HashMap底层原理
    一、HashMap底层实现原理解析我们常见的有数据结构有三种结构:数组结构;链表结构;哈希表结构。下面我们来看看各自的数据结构的特点:1)数组结构:存储区间连续、内存占用严重、空间复杂度大优点:随机读取和修改效率高,原因是数组是连续的(随机访问性强,查找速度快)缺点:插入和删除数据......
  • HashMap底层原理
    一、HashMap底层实现原理解析我们常见的有数据结构有三种结构:数组结构;链表结构;哈希表结构。下面我们来看看各自的数据结构的特点:1)数组结构:存储区间连续、内存占用严重、空间复杂度大优点:随机读取和修改效率高,原因是数组是连续的(随机访问性强,查找速度快)缺点:插入和删除数据......
  • HashMap底层原理
    一、HashMap底层实现原理解析我们常见的有数据结构有三种结构:数组结构;链表结构;哈希表结构。下面我们来看看各自的数据结构的特点:1)数组结构:存储区间连续、内存占用严重、空间复杂度大优点:随机读取和修改效率高,原因是数组是连续的(随机访问性强,查找速度快)缺点:插入和删除数据......
  • 深入探究Java中的Map数据结构
    引言:在Java编程中,Map是一种重要的数据结构,它提供了键值对的存储和检索功能。在本篇博客文章中,我们将深入探究Java中的Map,包括不同实现类的比较,常见的用法和一些高级技巧。通过深入理解Map的内部机制和使用方法,你将能够更好地应用它解决实际问题。一、Map概述Map是Java中的一个接......
  • 分享6款文字语音生成驱动虚拟数字人说话的开源项目
    一、FACEGOOD的Audio2Facegithub地址:github.com/FACEGOOD/FA…FACEGOOD对输入和输出数据做了相应的调整,声音数据对应的标签不再是模型动画的点云数据而是模型动画的blendshape权重。FACEGOOD主要完成Audio2Face部分,ASR、TTS由思必驰智能机器人完成。如果你想用自己的......
  • 数据结构和算法-2023.07.01
    数据结构杂记回忆以前的一些零散的知识点杂谈......
  • go src - sync.Map
    前言在并发编程中,我们经常会遇到多个goroutine同时操作一个map的情况。如果在这种情况下直接使用普通的map,那么就可能会引发竞态条件,造成数据不一致或者更严重的问题。sync.Map是Go语言中内置的一种并发安全的map,但是他的实现和用法与普通的map完全不同,这篇文章将详细介绍这些区......
  • Map详解
    背景介绍我们在日常的开发的过程中,一直都有在使用Map存储数据。但是Map的底层原理,以及Map的Key值为什么不能重复,Map中的key值和Hash有什么关系大家都清楚吗,如果我们把这些内容都搞清楚了我们在使用Map的时候才会得心应手,排查关于Map相关的问题才会更加的容易,才会更快的去定位问题出......
  • Redis数据结构——快速列表(quicklist)1
    Redis数据结构——快速列表(quicklist)一、什么是quicklistquicklist是Redis3.2版本以后针对链表和压缩列表进行改造的一种数据结构,是zipList和linkedList的混合体,相对于链表它压缩了内存。进一步的提高了效率。quicklist其实就是简单的双链表,但每个双链表节点中保存......
  • Redis数据结构——快速列表(quicklist)
    Redis数据结构——快速列表(quicklist)一、什么是quicklistquicklist是Redis3.2版本以后针对链表和压缩列表进行改造的一种数据结构,是zipList和linkedList的混合体,相对于链表它压缩了内存。进一步的提高了效率。quicklist其实就是简单的双链表,但每个双链表节点中保存......