Java 集合深入理解(14):Map 概述

终于把 List 常用的几种容器介绍完了,接下来开始 Map 的相关介绍。

什么是 Map

Java 中的 Map 接口 是和 Collection 接口 同一等级的集合根接口,它 表示一个键值对 (key-value) 的映射。类似数学中 函数 的概念。

数学中的函数:

一个 Map 中,任意一个 key 都有唯一确定的 value 与其对应,这个 key-value 的映射就是 map。

Map 中元素的顺序取决于迭代器迭代时的顺序,有的实现类保证了元素输入输出时的顺序,比如说 TreeMap;有的实现类则是无序的,比如 HashMap。

Map 的三个 collection 视图:

Map 接口提供了三种角度来分析 Map:

  • KeySet
  • Values
  • Entry

1.KeySet

KeySet 是一个 Map 中键(key)的集合,以 Set 的形式保存,不允许重复,因此键存储的对象需要重写 equals() 和 hashCode() 方法。

在上图就是保存 AA, BB, CC, DD… 等键的集合。

可以通过 Map.keySet() 方法获得。

2.Values

Values 是一个 Map 中值 (value) 的集合,以 Collection 的形式保存,因此可以重复。

在上图就是保存 90,90,56,78… 等值的集合。

通过 Map.values() 方法获得。

3.Entry

Entry 是 Map 接口中的静态内部接口,表示一个键值对的映射,例如上图中 AA-90 这一组映射关系。

Entry 具有上图中的方法:

  • getKey() , 获取这组映射中的键 key
  • getValue() , 获取这组映射中的值 value
  • setValue() , 修改这组映射中的值
  • hashCode() , 返回这个 Entry 的哈希值
  • equals() , 对比 key-value 是否相等

通过 Map.entrySet() 方法获得的是一组 Entry 的集合,保存在 Set 中,所以 Map 中的 Entry 也不能重复。

public Set<Map.Entry<K,V>> entrySet();

Map 的三种遍历方式

根据 Map 提供的三种视图,可以有三种 map 遍历方式 :

1.使用 keySet 遍历:

    Set set = map.keySet();
    for (Object key : set) {
        System.out.println(map.get(key));
    }

2.使用 values 遍历:

    Collection values = map.values();
    Iterator iterator = values.iterator();
    while (iterator.hasNext()){
        System.out.println("value " + iterator.next());
    }

3.使用 Entry 遍历

    Set entrySet = map.entrySet();
    for (Object o : entrySet) {
        Map.Entry entry = (Map.Entry) o;
        System.out.println(entry);      //key=value
        System.out.println(entry.getKey() + " / " + entry.getValue());
    }

Map 的实现类

Map 的实现类主要有 4 种:

  • Hashtable
    • 古老,线程安全
  • HashMap
    • 速度很快,但没有顺序
  • TreeMap
    • 有序的,效率比 HashMap 低
  • LinkedHashMap
    • 结合 HashMap 和 TreeMap 的有点,有序的同时效率也不错,仅比 HashMap 慢一点

其中后三个的区别很类似Set 的实现类:

  • HashSet
  • TreeSet
  • LinkedHashSet

Map 的每个实现类都应该实现 2 个构造方法:

  1. 无参构造方法,用于创建一个空的 map
  2. 参数是 Map 的构造方法,用于创建一个包含参数内容的新 map

第二种构造方法允许我们复制一个 map。

虽然没有强制要求,但自定义 Map 实现类时最好都这样来。

总结

Map 有以下特点:

  • 没有重复的 key
  • 每个 key 只能对应一个 value, 多个 key 可以对应一个 value
  • key,value 都可以是任何引用类型的数据,包括 null
  • Map 取代了古老的 Dictionary 抽象类

注意: 可以使用 Map 作为 Map 的值,但禁止使用 Map 作为 Map 的键。因为在这么复杂的 Map 中,equals() 方法和 hashCode() 比较难定义。

另一方面,你应该尽量避免使用“可变”的类作为 Map 的键。如果你将一个对象作为键值并保存在 Map 中,之后又改变了其状态,那么 Map 就会产生混乱,你所保存的值可能丢失。

Thanks

https://docs.oracle.com/javase/8/docs/api/java/util/Map.html https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html https://docs.oracle.com/javase/tutorial/collections/implementations/map.html http://www.cnblogs.com/skywang12345/p/3308931.html http://www.nowamagic.net/librarys/veda/detail/1202

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xingoo, 一个梦想做发明家的程序员

Java程序员的日常 —— 《编程思想》持有对象

集合框架可以说是Java里面必备的知识点了,日常的使用中也会遇到各种情况需要使用到集合。下面就简单介绍下各种集合的使用场景: ? List List可以看...

2118
来自专栏闵开慧

HashMap与HashTable区别

1 HashMap不是线程安全的 hastmap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复...

2606
来自专栏java一日一条

Java程序员们最常犯的10个错误

Arrays.asList()会返回一个ArrayList对象,ArrayList类是Arrays的一个私有静态类,而不是java.util.ArrayList...

582
来自专栏java一日一条

Java程序员们最常犯的10个错误

Arrays.asList()会返回一个ArrayList对象,ArrayList类是Arrays的一个私有静态类,而不是java.util.ArrayList...

481
来自专栏java一日一条

如何用Map对象创建Set对象

Java中的Map和Set有不少相似之处。本文将分享一个把Map类转化成Set类的小技巧。

711
来自专栏JAVA高级架构

Java HashMap 遍历方式性能探讨

关于HashMap的实现这里就不展开了,具体可以参考 JDK7与JDK8中HashMap的实现 JDK8之前,可以使用keySet或者entrySet来遍历Ha...

39612
来自专栏F_Alex

数据结构与算法(二)-线性表之单链表顺序存储和链式存储

前言:前面已经介绍过数据结构和算法的基本概念,下面就开始总结一下数据结构中逻辑结构下的分支——线性结构线性表

1122
来自专栏个人分享

LinkedHashMap的实现原理(复习)

   LinkedHashMap是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不...

894
来自专栏小灰灰

JDK容器学习之Map: HashMap,TreeMap,LinkedHashMap对比小结

HashMap, TreeMap, LinkedHashMap 对比 1. 存储结构 HashMap 存储结构: 数组 + 链表 + 红黑树 ? LinkedH...

22210
来自专栏Jack的Android之旅

疯狂java笔记之线性表

从数据的逻辑结构来分,数据元素之间存在的关联关系被称为数据的逻辑结构。归纳起来,应用程序中的数据大致哟如下四种基本的逻辑结构。

992

扫码关注云+社区