Map接口

package map;
// Map 和 Collection 没有关系,只不过也可以说为是一种数据的集合。

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

/**
 * java.util.Map  查找表
 * Map 在 java 中是一种非常常用的数据结构,它体现的结构是一个多行两列的表格。
 * 其中左列称为 key,右列称为 value。
 *
 * Map总是成对保存数据,并且总是根据key获取对应的 value ,
 * 因此我们可以将查询条件作为 key,查询对应的结果作为 value 保存到 Map中。
 *
 * Map有一个要求:key 不允许重复(使用key自身的equals比较判断)
 *
 * java.util.Map 接口是所有Map的顶级接口,规定了 Map 的相关功能。
 * 常用实现类:
 *      java.util.HashMap: 称为散列表,是使用散列算法实现的Map,是当今查询速度最快的数据结构。
 *      java.util.TreeMap: 是使用二叉树实现的Map。
 *
 * java.util.HashMap:
 * JDK8以前,HashMap由数组+链表组成,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,
 * 如果定位到的数组位置不含链表,那么查找、添加等操作很快,仅需一次寻址即可;
 * 如果定位到的数组包含链表,对于添加操作,首先遍历链表,存在即覆盖,否则新增。
 * 对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一对比查找。
 * 所以,出于性能考虑,HashMap中的链表出现的越少,性能才会越好。
 *
 * JDK8以后,HashMap由数组+链表+红黑树组成,新增了红黑树作为底层数据结构,
 * 结构变得复杂了,但是效率也变得更高效了。
 * 当一个值要存储到Map中的时候会根据key的值来计算出它的hash值,通过哈希值来确认在数组中的位置,
 * 如果发生哈希碰撞就以链表的形式存储,
 * 但是如果链表过长的话,HashMap会把这个链表转换为红黑树来存储。
 * (当链表的值超过8则会转红黑树,当链表的值小于6则会从红黑树转回链表)
 *
 * java.util.TreeMap:
 * Tree(树)是计算机存储数据的一种结构,因为存储类型和显示生活中的树类似,所以被称为树。
 * 二叉树是最常用的树形结构,每个节点最多能有两个子节点,
 * 它的左节点比父节点要小,右节点比父节点要大,它的高度决定了查找的效率。
 * 1. 当查找时,会先进行当前节点的比较,如果相等的话,就直接返回当前节点;
 * 如果比当前节点小,则继续查找当前节点的左节点,如果比当前节点大,则继续查找当前节点的右节点。
 * 2. 插入时,先查找要插入的父节点,找到父节点后,通过比较与父节点的大小,决定要插入节点的位置。
 * 3. 删除时,先查找到要删除的节点,如果待删除的节点是叶子节点,则直接删除。
 * 如果待删除的节点不是叶子节点,就删除该子树
 *
 *  红黑树是每个节点都带有颜色属性的二叉树,颜色或红色或黑色,
 *  在二叉树强制的一般要求外,对于任何有效的红黑树,增加了如下的额外要求:
 *  1.节点是红色或黑色
 *  2.根节点是黑色
 *  3.所有叶子都是黑色
 *  4.每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色节点)
 *  5.从任一节点延伸出的每个叶子的所有路径都包含相同数目的黑色节点
 *
 * 红黑树是一种特殊的二叉树,有了颜色的划分,效率会比普通二叉树会更高。
 * HashMap 和 TreeMap 的底层都有二叉树
 * @author YanLy
 * @date 2021/6/5  15:17
 */
public class MapDemo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        /*
        V put (K k,V v)
        将给定的键值对存入Map中,由于key不允许重复,
        若使用已有的key存入value时则为替换value操作,返回值为原value,
        如果使用的是没有存在过的key 则返回null
         */
        map.put("数学",100);
        map.put("英语",70);
        map.put("语文",90);

        System.out.println(map);
        /*
        如果Map的value是包装类型时,在接收value值的时候一定要用包装类类型的变量来接收,
        不要使用对应的基本类型变量来接收,避免因为自动拆箱出现空指针异常。
         */
        Integer value = map.put("政治",91);
        System.out.println(value); // null
        map.put("物理",78);
        map.put("化学",66);
        map.put("生物",90);
        System.out.println(map);
        // put 返回值为null时自动拆箱会出现空指针异常
//        int value1 = map.put("政治1",92);// NullPointerException
//        System.out.println(value1);
        value = map.put("政治",88); // 替换了 "政治" 的这个key这个 value
        System.out.println("被替换的value: "+value); // 91

        System.out.println(map);

        /*
        获取Map的元素个数,每组键值对算一个元素
         */
        int size = map.size();
        System.out.println("size: "+size); // 7
        /*
        V get(Object k)
        根据给定的key获取对应的value,如果给定的key不存在,则返回值为null
         */
        value = map.get("数学");
        System.out.println("数学: "+value); // 数学: 100
        value = map.get("体育");
        System.out.println("体育: " + value); // 体育: null
        /*
        V remove(Object key)
        删除当前Map中给定的key所对应的键值对,返回值为这个key对应的value
         */
        value = map.remove("数学");
        System.out.println(map); // {政治=88, 物理=78, 生物=90, 化学=66, 语文=90, 英语=70}
        System.out.println("被删除的key数学对应的value: " + value); // 被删除的key数学对应的value: 100

        /*
        boolean containKey(Object key)
        判断当前Map是否包含指定的key

        boolean containValue(Object value)
        判断当前Map是否包含指定的value
         */
        boolean ck = map.containsKey("英语");
        System.out.println("是否包含key: "+ck); // 是否包含key: true
        boolean cv = map.containsValue(99);
        System.out.println("是否包含value: "+cv); // 是否包含value: false
    }
}
package map;

import java.util.*;

/**
 * 面试题:Map的遍历方式有几种?
 * Map提供了三种遍历方式:
 * 1.遍历所有的key,使用keySet()方法,
 * 该方法会将Map中所有的key存放到一个Set集合中并返回。
 * 2.遍历所有的键值对,使用EntrySet()方法,
 * 该方法会将Map中所有的键值对以Entry的形式存放并放入到Set集合中返回。
 * 3.遍历所有的value(相对不常用),使用values()方法,
 * 该方法会将Map中所有的value存放到一个Collection集合中并返回。
 *
 * @author YanLy
 * @date 2021/6/5  16:17
 */
public class MapDemo2 {
    public static void main(String[] args) {

        Map<String,Integer> map = new HashMap<>();

        map.put("数学",100);
        map.put("英语",70);
        map.put("语文",90);
        map.put("物理",78);
        map.put("化学",66);
        map.put("生物",90);
        System.out.println(map); // {物理=78, 生物=90, 数学=100, 化学=66, 语文=90, 英语=70}

        /*
        遍历所有的key: Set<K> keySet()
        将当前Map中所有的key以一个Set集合的形式返回。
        遍历该集合等同于遍历Map中所有的key。
         */
        Set<String> keySet = map.keySet();

        System.out.println(keySet); // [物理, 生物, 数学, 化学, 语文, 英语]

        for (String key:keySet) {
            System.out.println("key: " + key);
        }

        keySet.forEach(k-> System.out.println("k: "+k));

        /*
        遍历所有的键值对
        Set<Entry> entrySet()
        将当前Map中的每一组键值对以若干个Entry实例保存,并且存入一个Set集合后返回。

        java.util.Map.Entry
        Entry接口位于Map接口中,使用时需要用Map.Entry才能访问
        该类的每一个实例用于表示Map中的一组键值对
        该类提供了两个常用的方法:
        K getKey()
        K getValue()
         */
        // -- Map 接口中 有一个 Entry 接口
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        for(Map.Entry<String,Integer> e:entrySet){
//            System.out.println("e: " +e);
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key+" : "+value);
        }

        // JDK8之后,Map也提供了forEach方法,用lambda表达式遍历
        map.forEach((k,v)-> System.out.println(k+" - "+v));

        /*
        遍历所有value
        Collection<V> values()
        将当前Map中的所有Value以一个集合形式返回。
         */
        Collection<Integer> values = map.values();
        for(Integer value:values){
            System.out.println("value: "+ value);
        }
        values.forEach(v -> System.out.println("v: " + v));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值