Java入门Day11:Map接口

1. Map接口

1.Map和Collection并列存在,用于保存具有映射关系的键值对Key-Value(双列元素)。
2.Map中的Key和Value是封装在HashMap&Node对象中的。
3.Map中的Key不允许重复,原因和HashSet一样,当有重复的Key时,就等价于替换。
4.Map中可以有多个重复的Value,但需要不同的Key。
5.Map中Key可以为null,但只能有一个,Value可以有多个为空。
6.常用的Map的Key是String,但可以用任何Object类型作为Key。

1.1 底层实现

K-V是存放在HashMap $ Node引用的Node对象中,为了方便遍历,创建了EntrySet集合,其中的元素类型是Entry,它的对象是指向K-V的。
entrySet中,定义的类型是Map.Entry,但是实际上存放的是HashMap $ Node的地址,指向了HashMap $ Node中的K-V,并不是将K-V复制了一份存放到新空间。
entrySet中将K和V分别用实现了Set接口的

1.2 常用方法

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

public class Demo01 {
    public static void main(String[] args) {
        Map<Object, Object> map = new HashMap<>();
        map.put("No1","吕布");
        map.put("No2","张飞");
        map.put("No1","赵云");//相对键,相当于替换对应值
        System.out.println(map);

        //根据Key删除映射关系  remove
        map.remove("No2");

        //获取键对应的值   get
        map.get("No1");

        //获取元素的个数  size
        System.out.println(map.size());

        //判读个数是否为0 isEmpty
        System.out.println(map.isEmpty());

        //清除 clear
        map.clear();

        //查找键是否存在 containsKey
        System.out.println(map.containsKey("赵云"));
    }
}

1.3 Map接口的遍历

  • 通过取出Key来获取value的值
  • 通过Values直接取出所有Value,再用Collection接口的方法遍历
    因为Value是在entrySet中是实现了Collection接口的
    -通过entrySet返回K-V,又entrySet是实现了Collection接口的,可以用Collection的方法遍历
import java.util.*;

public class Demo02 {
    public static void main(String[] args) {
        Map<Object, Object> map = new HashMap<>();
        map.put("No1", "吕布");
        map.put("No2", "张飞");
        map.put("No1", "赵云");//相对键,相当于替换对应值

        //Map接口的遍历,先取出所有的key,通过key来获取value值
        Set key = map.keySet();
        //迭代器遍历
        Iterator iterator = key.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(map.get(next));
        }

        //增强for循环
        for (Object obj:
                key) {
            System.out.println(map.get(key));
        }

        //也可以通过 Values直接取出所有的value,再通过Collection接口遍历的方法来遍历
        Collection values = map.values();

        //通过entrySet返回k-v
        Set entrySet = map.entrySet();
        //增强for循环
        for (Object entry:
             entrySet) {
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey()+"-"+m.getValue());
        }
        //迭代器
        Iterator iterator1= entrySet.iterator();
        while (iterator1.hasNext()) {
            Object next = iterator1.next();
            System.out.println(next);
            Map.Entry M = (Map.Entry) next;
            System.out.println(M.getKey()+"+"+M.getValue());
        }
    }
}

例子

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

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

import java.util.*;

public class Test {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put(01,new Employee("刘备",30000,01));
        map.put(02,new Employee("关羽",20000,02));
        map.put(03,new Employee("张飞",-50000,03));
        System.out.println("-------------");
        //取出key值遍历
        Set keys = map.keySet();
        for (Object key:
             keys) {
            Employee employee = (Employee) map.get(key);
            if (employee.getSalary()>18000){
                System.out.println(employee.getName());
            }
        }
        System.out.println("-------------");
        //取出value值遍历
        Collection values = map.values();
        for (Object value: values) {
            Employee employee = (Employee) value;
            if (employee.getSalary()>18000){
                System.out.println(employee.getName());
            }
        }
        System.out.println("-------------");
        //取出K-V进行遍历
        Set entrySet = map.entrySet();
        for (Object entry:entrySet) {
            Map.Entry et = (Map.Entry) entry;
            Employee employee = (Employee) et.getValue();
            if (employee.getSalary()>18000){
                System.out.println(employee.getName());
            }
        }
        System.out.println("-------------");

        //迭代器
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Object entry = iterator.next();
            Map.Entry et = (Map.Entry) entry;
            Employee employee = (Employee) et.getValue();
            if (employee.getSalary()>18000){
                System.out.println(employee.getName());
            }
        }
    }
}
class Employee{
    private String name;
    private int salary;
    private int id;

    public Employee(String name, int salary, int id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public int getId() {
        return id;
    }

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

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

2. HashMap 类

1.执行构造器 new HashMap()
初始化加载因子 loadfactor = 0.75
HashMap$Node[] table = null
2.执行put调用hash方法,计算key的hash值(h=key.hashCode())^(h>>>16)
3.执行putVal方法建立Node数组,创建table表,初始容量为16,按key的hash值获得索引,判断索引是否为空,创建Node空间,加入k-v
++size,比较size和临界值(12),如果size大于12,扩容。

3. HashTable 类

1.hashtable存放的也是键值对
2.hashtable的k和v都不能为null
3.hashtable的方法基本上和hashmap一致
4.hashtable是线程安全的

底层
底层有一个hashtable$entry数组,table表指向这个数组,初始化大小为11
临界值threshold=8
扩容:左移一位+1

3.1 Properties类

继承了Hashtable类,实现了Map接口
特点和Hashtable类似
可以用于properties文件中,加载数据到properties类对象,进行读取和修改
properties文件通常作为配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值