【Java】—— 集合框架:Map接口的常用方法和主要实现类HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

目录

6. Map接口

6.1 Map接口概述

6.2 Map中key-value特点

6.2 Map接口的常用方法

6.3 Map的主要实现类:HashMap

6.3.1 HashMap概述

6.3.2 练习

6.4 Map实现类之二:LinkedHashMap

6.5 Map实现类之三:TreeMap

6.6 Map实现类之四:Hashtable

6.7 Map实现类之五:Properties


6. Map接口

        现实生活与开发中,我们常会看到这样的一类集合:用户ID与账户信息、学生姓名与考试成绩、IP地址与主机名等,这种一一对应的关系,就称作映射。Java提供了专门的集合框架用来存储这种映射关系的对象,即java.util.Map接口。

6.1 Map接口概述

  • Map与Collection并列存在。用于保存具有映射关系的数据:key-value

    • Collection集合称为单列集合,元素是孤立存在的(理解为单身)。

    • Map集合称为双列集合,元素是成对存在的(理解为夫妻)。

  • Map 中的 key 和 value 都可以是任何引用类型的数据。但常用String类作为Map的“键”。

  • Map接口的常用实现类:HashMapLinkedHashMapTreeMap`Properties。其中,HashMap是 Map 接口使用频率最高的实现类。

6.2 Map中key-value特点

这里主要以HashMap为例说明。HashMap中存储的key、value的特点如下:

  • Map 中的 key用Set来存放不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法

  • key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value,不同key对应的value可以重复。value所在的类要重写equals()方法。

  • key和value构成一个entry。所有的entry彼此之间是无序的不可重复的

6.2 Map接口的常用方法

  • 添加、修改操作:

    • Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中

    • void putAll(Map m):将m中的所有key-value对存放到当前map中

  • 删除操作:

    • Object remove(Object key):移除指定key的key-value对,并返回value

    • void clear():清空当前map中的所有数据

  • 元素查询的操作:

    • Object get(Object key):获取指定key对应的value

    • boolean containsKey(Object key):是否包含指定的key

    • boolean containsValue(Object value):是否包含指定的value

    • int size():返回map中key-value对的个数

    • boolean isEmpty():判断当前map是否为空

    • boolean equals(Object obj):判断当前map和参数对象obj是否相等

  • 元视图操作的方法:

    • Set keySet():返回所有key构成的Set集合

    • Collection values():返回所有value构成的Collection集合

    • Set entrySet():返回所有key-value对构成的Set集合

举例:

import java.util.HashMap;

public class TestMapMethod {
    public static void main(String[] args) {
        //创建 map对象
        HashMap map = new HashMap();

        //添加元素到集合
        map.put("黄晓明", "杨颖");
        map.put("李晨", "李小璐");
        map.put("李晨", "范冰冰");
        map.put("邓超", "孙俪");
        System.out.println(map);

        //删除指定的key-value
        System.out.println(map.remove("黄晓明"));
        System.out.println(map);

        //查询指定key对应的value
        System.out.println(map.get("邓超"));
        System.out.println(map.get("黄晓明"));

    }
}

6.3 Map的主要实现类:HashMap

6.3.1 HashMap概述
  • HashMap是 Map 接口使用频率最高的实现类。

  • HashMap是线程不安全的。允许添加 null 键和 null 值。

  • 存储数据采用的哈希表结构,底层使用一维数组+单向链表+红黑树进行key-value数据的存储。与HashSet一样,元素的存取顺序不能保证一致。

  • HashMap 判断两个key相等的标准是:两个 key 的hashCode值相等,通过 equals() 方法返回 true。

  • HashMap 判断两个value相等的标准是:两个 value 通过 equals() 方法返回 true。

6.3.2 练习

练习1:添加你喜欢的歌手以及你喜欢他唱过的歌曲

例如:

public class SingerTest {
    public static void main(String[] args) {
        HashMap map = new HashMap();

        //添加1个歌手和其歌曲
        String singer1 = "周杰轮";
        ArrayList songs1 = new ArrayList();
        songs1.add("双截棍");
        songs1.add("稻香");
        songs1.add("青花瓷");
        songs1.add("发如雪");

        map.put(singer1,songs1);



        //添加1个歌手和其歌曲
        String singer2 = "陈毅讯";
        ArrayList songs2 = new ArrayList();
        songs2.add("浮夸");
        songs2.add("十年");
        songs2.add("富士山下");
        songs2.add("好久不见");

        map.put(singer2,songs2);


        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            // 是一个Map.Entry类型
            Map.Entry entry = (Map.Entry) iterator.next();
            System.out.println("歌手:" + entry.getKey());
            System.out.println("歌手:" + entry.getValue());
        }

    }
}

 

练习2:二级联动

        将省份和城市的名称保存在集合中,当用户选择省份以后,二级联动,显示对应省份的地级市供用户选择。

效果演示:

package exer3;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      将省份和城市的名称保存在集合中,当用户选择省份以后,二级联动,显示对应省份的地级市供用户选择。
 * @Author zyjstart
 * @Create:2024/10/3 23:23
 */
class CityMap{

    public static Map model = new HashMap();

    static {
        model.put("北京", new String[] {"北京"});
        model.put("上海", new String[] {"上海"});
        model.put("天津", new String[] {"天津"});
        model.put("重庆", new String[] {"重庆"});
        model.put("黑龙江", new String[] {"哈尔滨","齐齐哈尔","牡丹江","大庆","伊春","双鸭山","绥化"});
        model.put("吉林", new String[] {"长春","延边","白山","白城","四平","松原"});
        model.put("河北", new String[] {"石家庄","张家口","邯郸","邢台","唐山","保定","秦皇岛"});
    }

}

public class CityMapTest {
    public static void main(String[] args) {

        //1、获取Map,并遍历map中的所有key
        Map map = CityMap.model;
        //取出所有key,省份
        Set provinces = map.keySet();
        for (Object province : provinces) {
            System.out.print(province + "\t\t");
        }
        System.out.println();

        //2、根据提示,从键盘获取省份,判断此身份是否存在,如果存在 遍历其value中的各个城市
        // 如果不存在,提示用户重新输入
        Scanner sc = new Scanner(System.in);
        String[] cities;
        while (true){
            System.out.println("请选择你所在的省份:");

            String province = sc.next();

            // 获取省份对应的各个城市构成的String[]
            cities = (String[]) map.get(province);
            // 判断获取的省份是否存在
            if (cities == null || cities.length == 0){
                System.out.println("你输入的省份有误,请重新输入:");
            }else {
                break;  //意味着用户输入的省份存在,则跳出当前循环
            }
        }
        for (int i = 0; i < cities.length; i++) {
            System.out.print(cities[i] + "\t\t");
        }
        System.out.println();
        //3、根据提示,从键盘获取城市,遍历各个城市的String[],判断输入的城市是否存在于此数组中
        //如果存在,信息登记完毕,如果不存在,提示用户重新输入
        l:while (true){
            System.out.println("请选择你所在的城市:");
            String city = sc.next();

            for (int i = 0; i < cities.length; i++) {
                if (city.equals(cities[i])){
                    System.out.println("信息登记完毕!");
                    break l;  // 结束指定标签位置循环
                }
            }
            //没找到
            System.out.println("输入的城市有误,请重新输入:");
        }

        sc.close();
    }
}

6.4 Map实现类之二:LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类

  • 存储数据采用的哈希表结构+链表结构,在HashMap存储结构的基础上,使用了一对双向链表记录添加元素的先后顺序,可以保证遍历元素时,与添加的顺序一致。

  • 通过哈希表结构可以保证键的唯一、不重复,需要键所在类重写hashCode()方法、equals()方法。

public class TestLinkedHashMap {
    public static void main(String[] args) {
        LinkedHashMap map = new LinkedHashMap();
        map.put("王五", 13000.0);
        map.put("张三", 10000.0);
        //key相同,新的value会覆盖原来的value
        //因为String重写了hashCode和equals方法
        map.put("张三", 12000.0);
        map.put("李四", 14000.0);
        //HashMap支持key和value为null值
        String name = null;
        Double salary = null;
        map.put(name, salary);

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

6.5 Map实现类之三:TreeMap

  • TreeMap存储 key-value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 key-value 对处于有序状态

  • TreeSet底层使用红黑树结构存储数据

  • TreeMap 的 Key 的排序:

    • 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException

    • 定制排序:创建 TreeMap 时,构造器传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

  • TreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0。

6.6 Map实现类之四:Hashtable

  • Hashtable是Map接口的古老实现类,JDK1.0就提供了。不同于HashMap,Hashtable是线程安全的。

  • Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构(数组+单向链表),查询速度快。

  • 与HashMap一样,Hashtable 也不能保证其中 Key-Value 对的顺序

  • Hashtable判断两个key相等、两个value相等的标准,与HashMap一致。

  • 与HashMap不同,Hashtable 不允许使用 null 作为 key 或 value。

面试题:Hashtable和HashMap的区别

HashMap:底层是一个哈希表(jdk7:数组+链表;jdk8:数组+链表+红黑树),是一个线程不安全的集合,执行效率高
Hashtable:底层也是一个哈希表(数组+链表),是一个线程安全的集合,执行效率低

HashMap集合:可以存储null的键、null的值
Hashtable集合,不能存储null的键、null的值

Hashtable和Vector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了。所以HashMap是Map的主要实现类,Hashtable是Map的古老实现类。

Hashtable的子类Properties(配置文件)依然活跃在历史舞台
Properties集合是一个唯一和IO流相结合的集合

6.7 Map实现类之五:Properties

  • Properties 类是 Hashtable 的子类,该对象用于处理属性文件

  • 由于属性文件里的 key、value 都是字符串类型,所以 Properties 中要求 key 和 value 都是字符串类型

  • 存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值