Map接口

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

1. Map接口概述

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

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

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

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

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

    image-20220409001015034

2. Map中key-value特点

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

image-20220409001213720

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

    image-20220514190412763

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

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

3. 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集合

举例:

package com.atguigu.map;  
​  
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("黄晓明"));  
​  
    }  
}

4. Map的主要实现类:HashMap

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

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

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

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

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

5. 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. 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。

public class TestTreeMap {  
    /*  
    * 自然排序举例  
    * */  
    @Test  
    public void test1(){  
        TreeMap map = new TreeMap();  
​  
        map.put("CC",45);  
        map.put("MM",78);  
        map.put("DD",56);  
        map.put("GG",89);  
        map.put("JJ",99);  
​  
        Set entrySet = map.entrySet();  
        for(Object entry : entrySet){  
            System.out.println(entry);  
        }  
​  
    }  
​  
    /*  
    * 定制排序  
    *  
    * */  
    @Test  
    public void test2(){  
        //按照User的姓名的从小到大的顺序排列  
​  
        TreeMap map = new TreeMap(new Comparator() {  
            @Override  
            public int compare(Object o1, Object o2) {  
                if(o1 instanceof User && o2 instanceof User){  
                    User u1 = (User)o1;  
                    User u2 = (User)o2;  
​  
                    return u1.name.compareTo(u2.name);  
                }  
                throw new RuntimeException("输入的类型不匹配");  
            }  
        });  
​  
        map.put(new User("Tom",12),67);  
        map.put(new User("Rose",23),"87");  
        map.put(new User("Jerry",2),88);  
        map.put(new User("Eric",18),45);  
        map.put(new User("Tommy",44),77);  
        map.put(new User("Jim",23),88);  
        map.put(new User("Maria",18),34);  
​  
        Set entrySet = map.entrySet();  
        for(Object entry : entrySet){  
            System.out.println(entry);  
        }  
    }  
}  
​  
class User implements Comparable{  
    String name;  
    int age;  
​  
    public User(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
​  
    public User() {  
    }  
​  
    @Override  
    public String toString() {  
        return "User{" +  
                "name='" + name + '\'' +  
                ", age=" + age +  
                '}';  
    }  
    /*  
    举例:按照age从小到大的顺序排列,如果age相同,则按照name从大到小的顺序排列  
    * */  
    @Override  
    public int compareTo(Object o) {  
        if(this == o){  
            return 0;  
        }  
​  
        if(o instanceof User){  
            User user = (User)o;  
            int value = this.age - user.age;  
            if(value != 0){  
                return value;  
            }  
            return -this.name.compareTo(user.name);  
        }  
        throw new RuntimeException("输入的类型不匹配");  
    }  
}

7. 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流相结合的集合

8. Map实现类之五:Properties

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

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

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

@Test  
public void test01() {  
    Properties properties = System.getProperties();  
    String fileEncoding = properties.getProperty("file.encoding");//当前源文件字符编码  
    System.out.println("fileEncoding = " + fileEncoding);  
}  
@Test  
public void test02() {  
    Properties properties = new Properties();  
    properties.setProperty("user","songhk");  
    properties.setProperty("password","123456");  
    System.out.println(properties);  
}  
​  
@Test  
public void test03() throws IOException {  
    Properties pros = new Properties();  
    pros.load(new FileInputStream("jdbc.properties"));  
    String user = pros.getProperty("user");  
    System.out.println(user);  
}
Java基础

Collection子接口2:Set接口

2025-8-10 15:33:59

Java基础

Collections工具类

2025-8-13 7:10:59

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索