java集合类史上最细讲解 - Map篇

简介: 1.Map接口介绍Map用于保存具有映射关系的数据:Key - Value对于Set,底层其实依然是一个Map,但是Set选择不使用Value,也就是Set的Value值始终是一个常量😁Map中的Key和Value可以是任何类型的数据,会封装到HashMap$Node对象中Map中的Key不能重复,但是Value可以重复,当有相同的Key时,等价与替换操作😀


1.Map接口介绍


Map用于保存具有映射关系的数据:Key - Value


对于Set,底层其实依然是一个Map,但是Set选择不使用Value,也就是Set的Value值始终是一个常量😁


Map中的Key和Value可以是任何类型的数据,会封装到HashMap$Node对象中


Map中的Key不能重复,但是Value可以重复,当有相同的Key时,等价与替换操作😀


2.Map接口分析


存放Map键值对是在HashMap$Node中


tab[i] = newNode(hash, key, value, null);
--
Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
    return new Node<>(hash, key, value, next);
}


那么这个Node节点的数据类型是什么样的呢?

我们来看一下源代码:(其还实现了Entry接口)


static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;  // 存放hash值
    final K key;  // 存放key值
    V value;  // 存放Value值
    Node<K,V> next;  // 存放下一个个节点,以形成链表结构
}


k-v为了方便程序员的遍历,还会创建一个EntrySet集合,该集合存放的元素类型是Entry,而一个Entry对象含有k,v,但是本质上这里的k-v值还是指向一个Node节点中的数据,也就是这里的k-v存放的依然是地址数据📕


// k-v存在有EntrySet的一个指向
Set set = map.entrySet();
System.out.println(set.getClass());  // class java.util.HashMap$EntrySet


那么,这个方便程序员遍历的特性是如何体现的呢?

原因是Map.Entry提供了两个非常重要的方法:K getKey(); V getValue();。所以我们可以通过如下的方式进行遍历Map:


Set set = map.entrySet();
System.out.println(set.getClass());
for (Object obj : set) {
    Map.Entry entry = (Map.Entry) obj;
    System.out.println(entry.getKey());
    System.out.println(entry.getValue());
}


那怎么证明Entry里面存放的k-v只是地址的指向呢?很简单

通过debug,我们先来看一下Map中存放的数据,其no2这个键的地址是@727



再来看一下set中no2键的地址,一模一样:🎉



3.Map接口方法


代码示例:


Map map = new HashMap();
// 添加键值对
map.put("no1","dahe");
map.put("no2","zhangsan");
// Key重复会进行替换
map.put("no1","lisi");
System.out.println(map);
// 根据键删除映射关系
map.remove("no1");
System.out.println(map);
// 根据key得到值
Object no2 = map.get("no2");
System.out.println(no2);
// 获取键值对数量
System.out.println(map.size());
// 判空
System.out.println(map.isEmpty());
// 清空
// map.clear();
// 查找键是否存在
System.out.println(map.containsKey("ok"));


4.Map遍历方式


第一式:取出所有的key,通过key取出对应的value


// 取出所有的key,通过key取出对应的value
Set keySet = map.keySet();
for (Object o : keySet) {
    System.out.println(o);
    System.out.println(map.get(o));
}


第二式:把所有的value值取出


// 把所有的value值取出
Collection values = map.values();
for (Object value : values) {
    System.out.println(value);
}


第三式:通过EntrySet来获取 k-v


// 通过EntrySet来获取 k-v
Set entrySet1 = map.entrySet();
for (Object o : entrySet1) {
    // 将entry 转成 Map.Entry
    Map.Entry m = (Map.Entry) o;
    System.out.println(m.getKey());
    System.out.println(m.getValue());
}



目录
相关文章
|
9天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
36 17
|
2天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
8 2
|
1天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
6天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
5天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
34 4
|
6天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
15 2
|
6天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
6天前
|
Java 开发者
|
10天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
11天前
|
存储 Java API
Java交换map的key和value值
通过本文介绍的几种方法,可以在Java中实现Map键值对的交换。每种方法都有其优缺点,具体选择哪种方法应根据实际需求和场景决定。对于简单的键值对交换,可以使用简单遍历法或Java 8的Stream API;对于需要处理值不唯一的情况,可以使用集合存储或Guava的Multimap。希望本文对您理解和实现Java中的Map键值对交换有所帮助。
14 1