集合——Map 接口

在这里插入图片描述

Map 接口实现类的特点

  1. MapCollection 并列存在。用于保存具有映射关系的数据:Key-Value
  2. Map 中的 keyvalue 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中
  3. Map 中的 key 不允许重复,原因和 HashSet 一样,前面分析过源码.
  4. Map 中的 value 可以重复
  5. Mapkey 可以为 nullvalue 也可以为 null,注意 keynull ,只能有一个, valuenull ,可以多个.
  6. 常用 String 类作为 Mapkey
  7. keyvalue 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value
  8. Map 存放数据的 key-value 示意图,一对 k-v 是放在一个 Node 中的,有因为 Node 实现了 Entry 接口,有些书上也说一对 k-v 就是一个 Entry


package collection_;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 9:04 2021/9/23
 */
public class Map_ {
    public static void main(String[] args) {
        // 1. Map 与 Collection 并列存在。用于保存具有映射关系的数据:Key-Value
        // 2. Map 中的 key 和 value 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中
        // 3. Map 中的 key 不允许重复,原因和 HashSet 一样,前面分析过源码.
        // 4. Map 中的 value 可以重复
        // 5. Map 的 key 可以为 null ,value 也可以为 null,注意 key 为 null ,只能有一个, value 为 null ,可以多个.
        // 6. 常用 String 类作为 Map 的 key
        // 7. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value
        Map map = new HashMap();
        map.put("no1", "Gin");
        map.put("no2", "Sherry");
        map.put("no2", "Vodka");
        map.put("no3", "Gin");
        map.put(null, null);
        map.put(null, "Rum");
        map.put("no4", null);
        map.put("no5", null);
        map.put(1, "Vermouth");
        map.put(new Object(), "Bourbon");

        System.out.println(map);
        // 通过 get 方法传入 key,会返回对应的 value
        System.out.println(map.get(1));

    }
}



Map 特点 8 :源码解读

  1. Map 存放数据的 key-value 示意图,一对 k-v 是放在一个 Node 中的,有因为 Node 实现了 Entry 接口,有些书上也说一对 k-v 就是一个 Entry

在这里插入图片描述


package collection_;

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

/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 15:48 2021/9/23
 */
public class MapSource_ {
    public static void main(String[] args) {

        Map map = new HashMap();
        map.put("no1", "Gin"); // k-v
        map.put("no2", "Sherry"); // k-v

        /*
            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);
            }

            解读:
            1. k-v 最后是 HashMap$Node node = newNode(hash, key, value, null);
            2. k-v 为了方便程序员的遍历,还会创建 EntrySet 集合,该集合存放的元素的类型为 Entry,
               而一个 Entry 对象就有 k-v,EntrySet<Entry<k,v>>,即:transient Set<Map.Entry<K,V>> entrySet;
            3. Entry 对象的 K, V 会指向 newNode 中的 key, value,即:数据并不会存放到 Entry 对象中
            4. 在 entrySet 中,定义的类型是 Map.Entry,但是实际存放的还是 HashMap$Node
            5. 这是因为 HashMap$Node 实现了 Map.Entry 接口: static class Node<K,V> implements Map.Entry<K,V>
            6. 当把 HashMap$Node 对象存放到 entrySet 就会方便程序员遍历,因为 Map.Entry 提供了两个重要的方法:
               K getKey()、V getValue()
         */

        Set set = map.entrySet();
        System.out.println(set.getClass()); // set 的运行类型:HashMap$EntrySet,set 中存放的就是一个一个的 Entry 对象
        for (Object obj : set) {
            // System.out.println(obj.getClass()); // 每一个 Entry 对象的运行类型:HashMap$Node

            // 通过 Map.Entry 的 getKey、getValue 方法获取 k-v
            Map.Entry entry = (Map.Entry)obj;
            System.out.println(entry.getKey() + " - " + entry.getValue());
            // no2 - Sherry
            // no1 - Gin
        }

        // 7. 还提供了 keySet() 和 values() 方法
        //    分别用于获取 map 中所有的 key 和 value
        Set set1 = map.keySet();
        System.out.println(set1.getClass()); // HashMap$KeySet
        Collection values = map.values();
        System.out.println(values.getClass()); // HashMap$Values
    }
}



在这里插入图片描述

Map 接口常用方法

  1. put:添加
  2. remove:根据键删除映射关系
  3. get:根据键获取值
  4. size:获取元素个数
  5. isEmpty:判断个数是否为0
  6. clear:清除
  7. containsKey:查找键是否存在

package collection_;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 16:56 2021/9/23
 */
public class MapSource {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("邓超", new Bookkk("",100));
        map.put("邓超", "孙丽");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");

        Object object = map.get("邓超");
        System.out.println(object);

        map.remove("鹿晗");

        System.out.println(map);
        boolean containsKey = map.containsKey(null);
        System.out.println(containsKey);
        System.out.println(map.containsValue("刘亦菲"));
        System.out.println(map.size());
        System.out.println(map.isEmpty());
        map.clear();

        /*
        输出结果:
            孙丽
            {邓超=孙丽, 宋喆=马蓉, 刘令博=null, null=刘亦菲, 王宝强=马蓉}
            true
            true
            5
            false
         */

    }
}
class Bookkk{
    private String name;
    private int price;

    public Bookkk() {
    }

    public Bookkk(String name, int price) {
        this.name = name;
        this.price = price;
    }
}


Map 的遍历



package collection_;

import java.util.*;

/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 17:04 2021/9/23
 */
public class MapFor {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("邓超", "孙丽");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");

        // 第一组:先取出所有的 key,再根据所有的 key 取出对应的 value
        Set keySet = map.keySet();
        // 1. 增强 for
        System.out.println("==== 增强 for ====");
        for (Object key : keySet) {
            System.out.println(key + " - " + map.get(key));
        }
        // 2. 迭代器
        System.out.println("==== 迭代器 ====");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            System.out.println(key + " - " + map.get(key));
        }

        // 第二组:去除所有的 values
        Collection values = map.values();
        // 这里可以使用所有的 collections 使用的遍历方法
        // 1. 增强 for
        System.out.println("==== 增强 for ====");
        for (Object value : values) {
            System.out.println(value);
        }
        // 2. 迭代器
        System.out.println("==== 迭代器 ====");
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object value = iterator1.next();
            System.out.println(value);
        }

        // 第三组:通过 entrySet 来获取 k-v
        // 1. 增强 for
        System.out.println("==== 第三种 增强 for k-v 方法 ====");
        Set entrySet = map.entrySet();
        for (Object entry : entrySet) {
            // 将 entry 转成 Map.Entry
            Map.Entry m = (Map.Entry)entry;
            System.out.println(m.getKey() + " - " + m.getValue());
        }
        // 2. 迭代器
        System.out.println("==== 第三种 迭代器 k-v 方法 ====");
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object entry =  iterator2.next();
            // System.out.println(entry.getClass()); // HashMap$Node
            // 向下转型:因为 Node 没有相应的方法,所以转型为 Entry
            Map.Entry m = (Map.Entry)entry;
            System.out.println(m.getKey() + " - " + m.getValue());
        }

    }
}



练习

使用 HashMap 添加 3 个员工对象,要求
键:员工id
值:员工对象

并遍历显示工资 > 28000 的员工(遍历方式最少两种)
员工类:姓名、工资、员工id



package collection_;

import java.util.*;

/**
 * @Author: Gin
 * @Description:
 * @Modified By: Gin
 * @Date: Created in 18:50 2021/9/23
 */
public class MapExercise {
    public static void main(String[] args) {

        Map map = new HashMap();
        map.put(1, new Emp("Gin", 35600, 1));
        map.put(2, new Emp("Vermouth", 40000, 2));
        map.put(3, new Emp("Vodka", 28000, 3));

        Set keySet = map.keySet();
        // 取出所有的 key ,增强 for
        System.out.println("===第一种遍历方式===");
        for (Object key : keySet) {
            Emp emp = (Emp) map.get(key);
            if(emp.getSal() > 28000){
                System.out.println(emp);
            }
        }
        // 取出所有的 key ,迭代器
        System.out.println("===第二种遍历方式===");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            Emp emp = (Emp) map.get(key);
            if(emp.getSal() > 28000){
                System.out.println(emp);
            }
        }

        // 使用 entrySet 迭代器遍历
        System.out.println("===第三种遍历方式===");
        Set entrySet = map.entrySet();
        Iterator iterator1 = entrySet.iterator();
        while (iterator1.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator1.next();
            Emp emp = (Emp) entry.getValue();
            if(emp.getSal() > 28000){
                System.out.println(emp);
            }
        }

    }
}
// 员工类:姓名、工资、员工id
class Emp{
    private String name;
    private double sal;
    private int id;

    public Emp() {
    }

    public Emp(String name, double sal, int id) {
        this.name = name;
        this.sal = sal;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Emp emp = (Emp) o;
        return Double.compare(emp.sal, sal) == 0 && id == emp.id && Objects.equals(name, emp.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, sal, id);
    }

    @Override
    public String toString() {
        return "Emp{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", id=" + id +
                '}';
    }
}



HashMap 小结

  1. Map 接口的常用实现类:HashMapHashtableProperties
  2. HashMapMap 接口使用频率最高的实现类。
  3. HashMap 是以 key-val 对的方式来存储数据(HashMap$Node类型)
  4. key 不能重复,但是值可以重复,允许使用 null 键和 null 值。
  5. 如果添加相同的 key,则会覆盖原来的 key-val ,等同于修改(key不会替换,val会替换)
  6. HashSet 一样,不保证映射的顺序,因为底层是以 hash 表的方式来存储的(jdk8HashMap底层:数组 + 链表 + 红黑树)
  7. HashMap 没有实现同步,因此是线程不安全的,方法没有做同步互斥操作,没有 synchronized
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值