一、Map 接口概述

  java.util.Map 接口专门用来存放键值对这种对象关系的对象。

  下面比较一下 Collection 与 Map 的区别:

    •  Collection 中的集合,元素是孤立存在的(理解是为单身),向集合存储元素采用一个个元素的方式存储。
    • Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找到所对应的值。
    • Collection 中的集合称为 单列集合,Map 中的集合称为双列集合
    • 注意:Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

    Map 集合的特点

    1. Map 集合是一个双列集合,一个元素包含两个值(一个 key,一个 value)

    2. Map 集合中的元素,key 和 value 的数据类型可以相同,也可以不同

    3. Map 集合中的元素,key 是不允许重复的,value 是可以重复的

    4. Map 集合中的元素,key 和 value 是 一一对应

    注意:Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量的数据类型可以相同,也可以不同。

二、Map 接口中常用方法

  常用方法

public V  put(K key,V value):把指定的键与指定的值添加到Map集合中
public void putAll(Map m):从指定映射中将所有映射关系复制到此映射中
public V remove(Object key):把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值
public V get(Object key):根据指定的键,在 Map 集合中获取对应的值
boolean containsKey(Object key) :是否包含某个key
boolean containsValue(Object value) :是否包含某个value
boolean isEmpty():是否为空
void clear():从此映射中移除所有映射关系
int size():返回此映射中的键-值映射关系数
public Set<K> keySet():获取 Map 集合中所有的键,存储到 Set 集合中
Collection<V> values():返回此映射中包含的值的 Collection 视图
public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。

    方法详解

    1、get() 方法

 public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
返回值:
key存在,返回对应的value值
key不存在,返回null

    2、containsKey() 方法

 boolean containsKey(Object key) 判断集合中是否包含指定的键。
包含返回true,不包含返回false

    3、remove() 方法

public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
返回值:V
key存在,v返回被删除的值
key不存在,v返回null

   4、put() 方法

 public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。
返回值:v
存储键值对的时候,key不重复,返回值V是null
存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value值

  

三、Map 集合遍历方法

  1、通过 键找值 的方式

    Map 集合中的方法:Set<K> keySet() 返回此映射中包含的键的 Set 视图。

    这里所有的key组成了一个Set集合,因为它们不可重复

    实现步骤

      (1)使用 Map 集合中的方法 keySet(),把 Map 集合所有的 key 取出来,存储到一个 set 集合中

      (2)通过 set 集合,获取 Map 集合中的每一个 key

      (3)通过 Map 集合中的方法 get(key),通过 key 找到 value。

     Demo:

 public static void main(String[] args) {
//创建Map集合对象
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178); //1.使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中
Set<String> set = map.keySet(); //2.遍历set集合,获取Map集合中的每一个key
//使用迭代器遍历Set集合
Iterator<String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
//3.通过Map集合中的方法get(key),通过key找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-------------------");
//使用增强for遍历Set集合
for(String key : set){
//3.通过Map集合中的方法get(key),通过key找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-------------------");
//使用增强for遍历Set集合
for(String key : map.keySet()){
//3.通过Map集合中的方法get(key),通过key找到value
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}

  2、通过 值 遍历

    Map 接口中的方法 Collection values():获取所有的 value,然后遍历它们。

    这里所有的value组成了一个Collection系列的集合,可能重复,也可能不重复

     Demo:

 @Test
public void test06(){
Map map = new HashMap(); map.put("张三", 175);
map.put("李四", 172);
map.put("王五", 178);
map.put("赵六", 182); Collection values = map.values();
for (Object value : values) {
System.out.println(value);
} }

  3、使用 Entry 对象遍历

    Map 中存放的是两种对象,一种称为 key(),一种称为 value(),它们在在 Map 中是一一对应关系,这一对对象又称做 Map 中的一个 Entry()

    因为key不可重复,那么所有的组合也就唯一了,所以所有的映射关系也是set集合。

    

    Entry 将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历 Map 集合时,就可以从每一个键值对( Entry )对象中获取对应的键与对应的值。

    既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法:

public K getKey() :获取Entry对象中的键。
public V getValue() :获取Entry对象中的值。

        Map集合中的方法: 

Set<Map.Entry<K,V>> entrySet()   返回此映射中包含的映射关系的 Set 视图。

       实现步骤

    (1)使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中

    (2)遍历Set集合,获取每一个Entry对象

    (3)使用Entry对象中的方法getKey()和getValue()获取键与值

   Demo:

 public static void main(String[] args) {
//创建Map集合对象
Map<String,Integer> map = new HashMap<>();
map.put("赵丽颖",168);
map.put("杨颖",165);
map.put("林志玲",178); //1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
Set<Map.Entry<String, Integer>> set = map.entrySet(); //2.遍历Set集合,获取每一个Entry对象
//使用迭代器遍历Set集合
Iterator<Map.Entry<String, Integer>> it = set.iterator();
while(it.hasNext()){
Map.Entry<String, Integer> entry = it.next();
//3.使用Entry对象中的方法getKey()和getValue()获取键与值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
System.out.println("-----------------------");
for(Map.Entry<String,Integer> entry:set){
//3.使用Entry对象中的方法getKey()和getValue()获取键与值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
}

  注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成 Set 之后就可以使用了。

四、Map 实现类

  HashMap 类

  LinkedHashMap 类

  TreeMap 类

  HashTable 类

  Properties 类

  1、HashMap 与 Hashtable 的区别与联系

    ① HashMap和Hashtable都是哈希表来实现的。

    ② HashMap和Hashtable判断两个 key 相等的标准是:两个 key 的hashCode 值相等,并且 equals() 方法也返回 true。因此,为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。

    ③ Hashtable是线程安全的,任何非 null 对象都可以用作键或值。

    ④ HashMap是线程不安全的,并允许使用 null 值和 null 键

  2、HashMap 与 LinkedHashMap 的区别与联系

    LinkedHashMap 是 HashMap 的子类。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。LinkedHashMap比HashMap要做的事多,效率低,只在需要维护顺序时再使用它。

  3、HashMap 与 TreeMap 区别与联系

    ① HashMap 是无序的;

    ② TreeMap 会按照 key 排大小顺序,基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

  4、Properties

        Properties 类是 Hashtable 的子类,不允许key和value是null,并且它的key和value的类型都是String。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串,通常用于存储配置属性。

  5、所有的Map的key不能重复,如何实现不重复?

    (1) HashMap、Hashtable、LinkedHashMap、Properties:依据key的hashCode和equals方法

    (2) TreeMap:依据key的大小,认为大小相等的两个key就是重复的

    注意:

      (1)如果key重复了,那么后面的value会替换原来的value,即把原来的值覆盖掉。

      (2)TreeMap要让key排大小,要么key类型本身实现了java.lang.Comparable接口,要么在创建TreeMap时,指定一个java.util.Comparator接口的实现类对象。

五、Map 的底层实现是什么?

  对于 Map 的五个实现类,可以分为两类:

  HashMap,LinkedHashMap,Hashtable,Properties 都是通过哈希表来实现的。

  TreeMap 是通过红黑树来实现的。

  HashMap 的底层实现:哈希表

    JDK1.7 以及之前:数组 + 链表的结构实现哈希表

    JDK1.8 以及之后:数组 + 链表/红黑树实现哈希表

  哈希表:

    在 JDK1.8 之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。

    JDK1.8中(之后),哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

  为什么要采用这样的特殊的数据结构呢?

  1、数组的优点:访问速度快,因为可以根据下标直接定位到某个元素

  2、链表的优点:不需要元素是挨着存储,不需要连续空间,在添加和删除元素时不需要移动元素,只需要修改前后元素的引用关系就可以。

          HashMap:会根据key的hashCode-->公式/算法-->[index],因为不同的hashCode值,可能得到的[index]是相同的,那么此时就冲突了,那么只能把[index]的多个映射关系用链表连接起来

  3、二叉树的优点:查找的速度比链表快

          旧版的HashMap,如果key的hashCode算出了[index]相同的话(我们称为冲突)都在一个table[index]下面

          如果严重的话,会导为什么要采用这样的特殊的数据结构呢?

          如果[index]下面的链表很长,就会导致查询速度减慢。当链表长到一定程度时,就需要把链表变为二叉树,以提高我们查询速度。

  

Java 之 Map 接口的更多相关文章

  1. JAVA ,Map接口 ,迭代器Iterator

    1.    Map 接口概述 java.util.Map 接口描述了映射结构, Map 接口允许以键集.值集合或键 - 值映射关系集的形式查看某个映射的内容. Java 自带了各种 Map 类. 这些 ...

  2. Java集合Map接口与Map.Entry学习

    Java集合Map接口与Map.Entry学习 Map接口不是Collection接口的继承.Map接口用于维护键/值对(key/value pairs).该接口描述了从不重复的键到值的映射. (1) ...

  3. Java Core - Map接口

    Map:是一组映射The java.util.Map interface represents a mapping between a key and a value. The Map interfa ...

  4. java中map接口hashMap以及Enty之间的用法和关系

    java中map接口hashMap以及Enty之间的转换 首先说的是map接口: Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value ...

  5. Java之Map接口(双列集合)

    Map集合概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对 ...

  6. Java集合——Map接口

    1.定义 Map用于保存存在映射关系<key,value>的数据.其中,key值不能重复(使用equals()方法比较),value值可以重复 2.方法 V  put(key,value) ...

  7. Java API —— Map接口

    1.Map接口概述         · 将键映射到值的对象         · 一个映射不能包含重复的键         · 每个键最多只能映射到一个值   2.Map接口和Collection接口的 ...

  8. Java容器——Map接口

    1.定义 Map用于保存存在映射关系<key, value>的数据.其中key值不能重复(使用equals()方法比较),value值可以重复. 2.常用实现类 HashMap:和Hash ...

  9. Java容器Map接口

    Map接口容器存放的是key-value对,由于Map是按key索引的,因此 key 是不可重复的,但 value 允许重复. 下面简单介绍一下Map接口的实现,包括HashMap,LinkedHas ...

随机推荐

  1. ISO/IEC 9899:2011 条款6.2.1——标识符的作用域

    6.2.1 标识符的作用域 1.一个标识符可以表示一个对象:一个函数:一个结构体.联合体或枚举的一个标签或一个成员,一个typedef名:一个标签名:一个宏名:或一个宏形参.相同的标识符可以在程序中不 ...

  2. java的servlet执行过程是怎么样的?

    java的servlet执行过程是怎么样   答: Servlet执行过程:程序第一次访问,会调用servlet的init()方法初始化(只执行一次),每次程序执行都会根据请求调用doGet()或者d ...

  3. 【用户体验度量】用户费力度评分(CES)

    http://www.woshipm.com/operate/2819882.html CES这个评分方式有点意思. 相关文章: http://www.woshipm.com/pd/856291.ht ...

  4. (十二)class文件结构:魔数和版本

    一.java体系结构 二.class格式文件概述 class文件是一种8位字节的二进制流文件, 各个数据项按顺序紧密的从前向后排列, 相邻的项之间没有间隙, 这样可以使得class文件非常紧凑, 体积 ...

  5. iOS-25个小技巧

    (一)关于UITableView  方法flashScrollIndicators:这个很有用,闪一下滚动条,暗示是否有可滚动的内容.可以在ViewDidAppear或[table reload]之后 ...

  6. hana客户端工具

    SAP HANA可视化客户端工具是C/S模式的,远程访问使用,都不是太方便,目前有一款基于WEB的可视化工具TreeSoft,通过浏览器就可以访问使用了,并且可以同时管理.维护.监控SAP HANA等 ...

  7. 创建.Net Core For WPF项目并且添加VS Code编译运行支持

    1.下载最新的Visual Studio 2019或者Preview版本,新建项目,找到"WPF App(.Net Core)"模板. 2.输入项目名称"NetCore- ...

  8. 海量无损高音质音乐文件分享180TB(持续更新)

    海量无损高音质音乐文件分享180TBWAV,flac,ape格式(持续更新),由于本人是音乐发烧爱好者,收集海量的无损音乐,已经分类好了,比较方便查找,但是本地没法存储,所有放在网盘中,并且我这边还会 ...

  9. halcon学习_字符识别1

    实例图片 大体步骤:1.读取图片                   2.图像预处理(阈值分割,提取标签部分,缩小处理区域)                  3.将标签区域的最小外接矩形,从原图中剪 ...

  10. Python 实现二分查找(递归版)

    二分查找 为什么使用二分查找: python中的列表,一般取值为遍历这个列表,直到取到你想要的值,但是如果你的列表是一个有着百万元素的列表呢,那样for循环遍历列表就会很慢,可能会循环几十万次,才能找 ...