Map集合基本介绍和方法解析

Map接口 和 常用方法
Map接口实现类的特点

注意:这里讲的是jdk8Map接口特点【必须掌握背下】

  1. MapCollection并列存在。用于保存具有映射关系的数据:Key_Valeu双列元素

  2. Map中的KeyValue可以是任何引用类型的数据,会封装到HashMap$Node对象中

  3. Map中的key不允许重复,原因和HashSet一样,当有相同的Key时,会替换掉原来的key-value

  4. Map中的Value可以重复

  5. Mapkey可以为nullvalue也可以为null,注意keynull只能有一个,valuenull可以有多个

  6. 常用String类作为Mapkey

  7. keyvalue之间存在单向一对一关系,即通过指定的key总能找到对应的value

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

    第八点的理解是:

    1.每个k-v最后是存放在 HashMap$Node = newNode(hash,key,value,null)

    2.要因为方便程序员的的遍历,还创建了EntrySet集合,该集合存放的元素是Entry,而一个Entry对象就有k,v EntrySet<EntrySet<Entry<K,V>>即:transient Set<Map.Entry<K,V>> entrySet;

    3.entrySet中, 定义的类型是Map.Entry ,但是实际上存放的还是 HashMap$Node 这时因为 static class Node<K,V> implements Map.Entry<K,V>【其实是多态数组】

    4.当把 HashMap$Node 对象 存放到entrySet 就方便我们的遍历, 因为 Map.Entry提供了重要方法 K getKey(); V getValue();

存储的顺序和取出的顺序是不一致的,本质底层是HashMap

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5pnxltkP-1647523718463)(E:\Typora笔记\java笔记\img\image-20220221154144884.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GGB3ZF4-1647523718465)(E:\Typora笔记\java笔记\img\image-20220221154122379.png)]

package com.hspedu.map_;

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


@SuppressWarnings({"all"})
public class MapSource_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1", "韩顺平");//k-v
        map.put("no2", "张无忌");//k-v
        map.put(new Car(), new Person());//k-v

        //老韩解读
        //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. entrySet 中, 定义的类型是 Map.Entry ,但是实际上存放的还是 HashMap$Node
        //   这时因为 static class Node<K,V> implements Map.Entry<K,V>
        //4. 当把 HashMap$Node 对象 存放到 entrySet 就方便我们的遍历, 因为 Map.Entry 提供了重要方法
        //   K getKey(); V getValue();

        Set set = map.entrySet();
        System.out.println(set.getClass());// HashMap$EntrySet
        for (Object obj : set) {

            //System.out.println(obj.getClass()); //HashMap$Node
            //为了从 HashMap$Node 取出k-v
            //1. 先做一个向下转型
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + "-" + entry.getValue() );
        }

        Set set1 = map.keySet();
        System.out.println(set1.getClass());
        Collection values = map.values();
        System.out.println(values.getClass());


    }
}

class Car {

}

class Person{

}
Map接口常用方法
Map接口常用方法
1.  put:添加
2.  remove:根据键删除映射关系
3.  get:根据键获取值
4.  size:获取元素个数
5.  isEmpty:判断个数是否为0
6.  clear:清除集合中所有元素
7.  containsKey:查找键是否存在
Modifier and TypeMethod and Description
voidclear() 从该地图中删除所有的映射(可选操作)。
boolean``containsKey(Object key)如果此映射包含指定键的映射,则返回true` 。
booleancontainsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true
Set<Map.Entry<K,V>>****entrySet() 返回此地图中包含的映射的Set视图。
booleanequals(Object o) 将指定的对象与此映射进行比较以获得相等性。
default voidforEach(BiConsumer<? super K,? super V> action) 对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。
Vget(Object key) 返回到指定键所映射的值,或 null如果此映射包含该键的映射。
default VgetOrDefault(Object key, V defaultValue) 返回到指定键所映射的值,或 defaultValue如果此映射包含该键的映射。
inthashCode() 返回此地图的哈希码值。
booleanisEmpty() 如果此地图不包含键值映射,则返回 true
Set<K>keySet() 返回此地图中包含的键的Set视图。
Vput(K key, V value) 将指定的值与该映射中的指定键相关联(可选操作)。
voidputAll(Map<? extends K,? extends V> m) 将指定地图的所有映射复制到此映射(可选操作)。
Vremove(Object key) 如果存在(从可选的操作),从该地图中删除一个键的映射。
default booleanremove(Object key, Object value) 仅当指定的密钥当前映射到指定的值时删除该条目。
default Vreplace(K key, V value) 只有当目标映射到某个值时,才能替换指定键的条目。
default booleanreplace(K key, V oldValue, V newValue) 仅当当前映射到指定的值时,才能替换指定键的条目。
default voidreplaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
intsize() 返回此地图中键值映射的数量。
Collection<V>values() 返回此地图中包含的值的Collection视图。
package collection_.collectionP.map_;

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

/**
 * @author: 海康
 * @version: 1.0
 */
public class Map01 {
    public static void main(String[] args) {
        Map map = new HashMap();
        // put 添加方法
        map.put(101,"海康");
        map.put(101,"西安"); // 注意是:当key值一样时,相当于替换了原来的 v
        map.put(102,"湛江");
        map.put(null,"广州");
        map.put(103,"杭州");
        map.put(104,"深圳");

        System.out.println(map);
        // remove 根据键删除映射关系
        Object remove = map.remove(null);
        System.out.println(remove);

        // get 根据键获取值
        Object o = map.get(101);
        System.out.println(o);

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

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

        // clear 清除集合中所有元素
        map.clear();

        // containsKsy 查找键是否存在
        System.out.println(map.containsKey(102));
    }
}
Map接口的遍历方法

由于元素的k-v是存在在HashMap$Node的内部类中,又因为HashMap$Node内部实现了Map.Entry接口,可以将HashMap$Node存放在Map.Entry中【其实是多态数组的方式】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wwygamHZ-1647523718466)(E:\Typora笔记\java笔记\img\image-20220221183935934.png)]

Map接口遍历方式是围着keySetvaluesEntry遍历的

遍历方法:

1.   keySet:获取所有的键
2.   entrySet:获取所有关系的 k-v
3.   values:获取所有的值
4.   containsKey:查找键是否存在

// 方式一:根据键遍历

// 方式二:根据值遍历

// 方式三:根据entrySet遍历

三种方式都对应的上图

package collection_.collectionP.map_;

import java.util.*;

/**
 * @author: 海康
 * @version: 1.0
 */
public class MapFor {
    public static void main(String[] args) {
        Map map = new HashMap();
        // put 添加方法
        map.put(101,"海康");
        map.put(101,"西安"); // 注意是:当key值一样时,相当于替换了原来的 v
        map.put(102,"湛江");
        map.put(null,"广州");
        map.put(103,"杭州");
        map.put(104,"深圳");

        // 方式一:根据获取键方式来遍历
        System.out.println("----键方式中增加for----");
        Set set = map.keySet();
        // 由于返回是set 集合所以可以使用增加for循环 和 迭代器方式
        // 1.1 增加for
        for (Object obj :set) {
            System.out.println(obj+"="+map.get(obj));
        }

        // 1.2 迭代器方式
        System.out.println("----键方式中迭代器----");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            System.out.println(obj+"-"+map.get(obj));
        }

        // 方式二:根据值来获取
        Collection values = map.values();
        // 由于根据值来获取返回是一个Collection集合,也有两种方式遍历
        // 一种是增加for  另一种是迭代器
        System.out.println("----根据值来获取中的增加for");
        for (Object obj:
             values) {
            System.out.println(obj);
        }

        System.out.println("----根据值来获取中的迭代器");
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object obj = iterator1.next();
            System.out.println(obj);
        }

        // 方式三:根据entrySet方式
        Set entrySet = map.entrySet();
        System.out.println("----根据entrySet方式中增加for");
        // 由于返回是Set集合还是有增加for和迭代器的方式遍历
        for (Object obj:
             entrySet) {
            // 由于要使用Map.Entry方法需要向下强转成Entry类
            // 使用Entry内部类中getKey方法和getValue方法
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey()+"-"+entry.getValue());
        }

        System.out.println("----根据entrySet方式中增加for");
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object obj = iterator2.next();
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey()+"-"+entry.getValue());
        }
        /**
         * 返回值:
         * ----键方式中增加for----
         * null=广州
         * 101=西安
         * 102=湛江
         * 103=杭州
         * 104=深圳
         * ----键方式中迭代器----
         * null-广州
         * 101-西安
         * 102-湛江
         * 103-杭州
         * 104-深圳
         * ----根据值来获取中的增加for
         * 广州
         * 西安
         * 湛江
         * 杭州
         * 深圳
         * ----根据值来获取中的迭代器
         * 广州
         * 西安
         * 湛江
         * 杭州
         * 深圳
         * ----根据entrySet方式中增加for
         * null-广州
         * 101-西安
         * 102-湛江
         * 103-杭州
         * 104-深圳
         * ----根据entrySet方式中增加for
         * null-广州
         * 101-西安
         * 102-湛江
         * 103-杭州
         * 104-深圳
         */
    }
}

课堂练习:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyUm9ehL-1647523718466)(E:\Typora笔记\java笔记\img\image-20220221202623212.png)]

package collection_.collectionP.map_;

import java.util.*;

/**
 * @author: 海康
 * @version: 1.0
 */
public class MapExercise01 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put(101,new Employee(101,"海康",68881.88));
        map.put(102,new Employee(102,"海康",68881.88));
        map.put(102,new Employee(102,"湛江",68881.88));// 由于key与上面的语句一样,所以value值会被替换掉
        map.put(103,new Employee(103,"南宁",6888.88));
        map.put(103,new Employee(103,"西安",8888.88));

//        System.out.println(map);
        // 遍历方式:
        // 方式一:使用key方式
        // 使用Key值中迭代器方式
        System.out.println("----使用Key值中迭代器方式----");
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            Employee employee = (Employee) map.get(obj);
            if (employee.getSalary() > 18000)
            System.out.println(obj+"-"+employee);
        }

        System.out.println("----使用Key值中增加for循环方式----");
        for (Object obj:
             set) {
            Employee employee = (Employee) map.get(obj);
            if (employee.getSalary() > 18000)
            System.out.println(obj+"-"+employee);
        }

        // 使用entrySet方式
        Set entrySet = map.entrySet();
        // 使用entrySet中迭代器方式
        System.out.println("----使用entrySet中迭代器方式----");
        Iterator iterator1 = entrySet.iterator();
        while (iterator1.hasNext()) {
            Object obj = iterator1.next();
            Map.Entry entry = (Map.Entry) obj;
            Employee employee = (Employee) entry.getValue();
            if (employee.getSalary() > 18000)
            System.out.println(entry.getKey()+"-"+ employee);
        }

        System.out.println("----使用entrySet中增加for方式----");
        for (Object obj :entrySet) {
            Map.Entry entry = (Map.Entry)obj;
            Employee employee = (Employee) entry.getValue();
            if (employee.getSalary() > 18000)
            System.out.println(entry.getKey()+"-"+employee);
        }

        /**
         * 返回值:
         * ----使用Key值中迭代器方式----
         * 101-Employee{Id=101, name='海康', salary=68881.88}
         * 102-Employee{Id=102, name='湛江', salary=68881.88}
         * ----使用Key值中增加for循环方式----
         * 101-Employee{Id=101, name='海康', salary=68881.88}
         * 102-Employee{Id=102, name='湛江', salary=68881.88}
         * ----使用entrySet中迭代器方式----
         * 101-Employee{Id=101, name='海康', salary=68881.88}
         * 102-Employee{Id=102, name='湛江', salary=68881.88}
         * ----使用entrySet中增加for方式----
         * 101-Employee{Id=101, name='海康', salary=68881.88}
         * 102-Employee{Id=102, name='湛江', salary=68881.88}
         */
    }
}

class Employee {
    private Integer Id;
    private String name;
    private double salary;

    public Employee() {
    }

    public Employee(Integer id, String name, double salary) {
        Id = id;
        this.name = name;
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return Double.compare(employee.salary, salary) == 0 && Objects.equals(Id, employee.Id) && Objects.equals(name, employee.name);
    }

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

    @Override
    public String toString() {
        return "Employee{" +
                "Id=" + Id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
}
package com.hspedu.map_;

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


@SuppressWarnings({"all"})
public class MapExercise {
    public static void main(String[] args) {
        //完成代码
        Map hashMap = new HashMap();
        //添加对象
        hashMap.put(1, new Emp("jack", 300000, 1));
        hashMap.put(2, new Emp("tom", 21000, 2));
        hashMap.put(3, new Emp("milan", 12000, 3));


        //遍历2种方式
        //并遍历显示工资>18000的员工(遍历方式最少两种)
        //1. 使用keySet  -> 增强for
        Set keySet = hashMap.keySet();
        System.out.println("====第一种遍历方式====");
        for (Object key : keySet) {
            //先获取value
            Emp emp = (Emp) hashMap.get(key);
            if(emp.getSal() >18000) {
                System.out.println(emp);
            }
        }

        //2. 使用EntrySet -> 迭代器
        //   体现比较难的知识点
        //   慢慢品,越品越有味道.
        Set entrySet = hashMap.entrySet();
        System.out.println("======迭代器======");
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry =  (Map.Entry)iterator.next();
            //通过entry 取得key 和 value
            Emp emp = (Emp) entry.getValue();
            if(emp.getSal() > 18000) {
                System.out.println(emp);
            }
        }

    }
}
/**
 * 使用HashMap添加3个员工对象,要求
 * 键:员工id
 * 值:员工对象
 *
 * 并遍历显示工资>18000的员工(遍历方式最少两种)
 * 员工类:姓名、工资、员工id
 */
class Emp {
    private String name;
    private double sal;
    private int id;

    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 String toString() {
        return "Emp{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", id=" + id +
                '}';
    }
}
HashMap小结

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6wxNtXd-1647523718467)(E:\Typora笔记\java笔记\img\image-20220221213341557.png)]

  1. Map接口常用实现类:HashMap HashtableProperties
  2. HashMapMap接口使用频率最高的实现类
  3. HashMap是以key-value对的方式来存储数据HashMap$Node类型,为方便将其存放在entrySet集合中
  4. key不能重复,但是值可以重复,允许使用null键和null
  5. 如果添加相同的key,则会覆盖原来的key-value上的value值【就是value被替换掉】
  6. HashMap一样,不保证映射的顺序,因为底层是以hash表的方式来存储的【jdk8的hashMap底层是 数组+链表+红黑树
  7. HashMap没有实现同步,因为是线程不安全的,方法没有做同步互斥的操作,没有synchronized关键字
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值