关于java:Java中的映射Map-入门篇

26次阅读

共计 3206 个字符,预计需要花费 9 分钟才能阅读完成。

前言

大家好啊,我是汤圆,明天给大家带来的是《Java 中的映射 Map – 入门篇》,心愿对大家有帮忙,谢谢

简介

后面介绍了汇合 List,这里开始简略介绍下映射 Map,相干类如下图所示

注释

Map 是一种存储键值对的数据汇合,键以散列或者树形构造进行存储;

为什么会设计 Map 接口呢?

假如咱们有一个员工类,外面有 Id 属性和姓名等其余信息,当初咱们把所有员工都存到 List 里,而后要找出 Id 为 001 的员工,你会发现,你须要从 List 中遍历每个对象,而后取出 Id 进行比拟;

你会发现这种查找法效率很低,有点杀鸡用牛刀的感觉;

这时如果有一个汇合类,能够以键值对映射的形式的存储员工信息(Id 作为键,员工信息作为值),那么就能够只遍历键列表,而后进行比拟;

你会发现这种查找法效率进步了很多,因为物尽其用了(比拟的是 Id,也只是取了 Id,没有节约);

这就是 Map 接口的作用,能够依据某个键去查找对应的信息,有点相似于数据库的设计。

Map 的品种

Map 次要有三种类型:HashMap(罕用)、TreeMap(树形构造)、LinkedHashMap(前两者的联合)

咱们先来看一下 Map 接口次要的几个办法:

  • V put(K key, V value):往 Map 中增加键值对,其中 key 为键,value 为值;如果 key 存在,则笼罩原有的值;如果不存在,则新建键值对。
  • V get(Object key):从 Map 中查找键 key 对应的值,如果没有,则返回 null
  • default V getOrDefault(Object key, V defaultValue):从 Map 中查找键 key 对应的值,如果没有,则返回第二个参数(设置的默认值);这里的修饰符 default 是用在接口办法中,示意这个办法在接口中曾经实现了,子类能够不实现(Java8 开始反对)
  • Set<K> keySet():返回 Map 中 Key 的汇合;之所以返回 Set,是因为 Map 中的 key 不能有反复,所以用 Set 最适宜了
  • Collection<V> values():返回 Map 中 Values 的汇合

上面咱们简略看下三者的区别

HashMap TreeMap LinkedHashMap
访问速度 适中
元素是否有序 无序 有序,默认按 key 排序 有序,默认按插入的程序
实用场景 一般的插入,查问(用的最多) 须要对 key 进行排序的场景(比方员工按年龄排序等) 须要保障查问和插入程序统一的场景(相似队列)

接下来咱们以 HashMap 为例,来介绍 Map 接口

HashMap

HashMap 外部是数组 + 链表的构造;

因为在增加键值对的时候,Key 做了 hash 解决,而后依照 hash 值进行排列;

  • 如果 hash 值没有反复,就依照数组的形式顺次排列;
  • 如果 hash 值有反复的,就增加到已有的键值对前面(Java8 当前是尾部插入),造成链表构造;

整体构造 如下图所示

这里只是简略介绍,当前再深刻理解

上面用代码示范一下

// 键值对汇合,键不能够反复
Map<String, Integer> map = new HashMap<>();
// 增加:首先会查看对应的 key 是否存在,如果不存在,则新建键值对,而后填充;如果存在,则笼罩已有的值
map.put("a", 1); // 这里的 1 会主动装箱为 Intege 类型
// 查问
int value1 = map.get("a");
int value2 = map.get("b"); 
System.out.println(map);

这里有个很有意思的景象,你感觉 value2 会是多少呢?

答案是多少都不是,因为程序运行到这一行就出错了,报空指针异样

不应该返回 null 吗?怎么会出错?

这里波及到拆箱和装箱的问题,下面咱们在增加 put 的时候,int 1 主动装箱为 Integer;

而后在获取 get 的时候,对应的也是要进行拆箱的,将 Integer 转为 int;

然而因为获取的 value = null,所以就相当于对 null 进行拆箱,后果就报错了。

解决办法就是严格依照 Map 的类型信息进行增加和获取;

将下面的代码加以批改,如下所示

// 键值对汇合,键不能够反复
Map<String, Integer> map = new HashMap<>();
// 增加:首先会查看对应的 key 是否存在,如果不存在,则新建键值对,而后填充;如果存在,则笼罩已有的值
map.put("a", 1); // 这里的 1 会主动装箱为 Intege 类型
// 查问
Integer value1 = map.get("a");
Integer value2 = map.get("b");
System.out.println(map);

此时 value2 就等于 null 了。

对于主动装箱和拆箱,网上资源很多,这里就不再细说了

TreeMap

TreeMap 在插入的时候,能够依照键的程序进行排序

它适宜用在排序比拟多的场景,性能会比 HashMap 差一些

LinkedHashMap

LinkedHashMap 领有 HashMap 的大部分长处,且保障了插入的程序,使得在查问的时候,能够依照插入的程序顺次读取

三者的排序比拟

上面用代码演示一下,顺次插入 100 个数,看看他们别离是怎么排序的

HashMapDemo.java

public class HashMapDemo {public static void main(String[] args) {
        // 键值对汇合,键不能够反复
        Map<String, Integer> map = new HashMap<>();
        // 倒序插入 100 个数
        int i =100;
        while (i-->0){map.put(""+i, i);
        }
        // 查问
        for (String str :
                map.keySet()) {
            // 这里会乱序输入
            System.out.println(str);
        }
    }
}

输入如下所示:很乱

TreeMapDemo.java


public class MapDemo {public static void main(String[] args) {
       
        // TreeMap
        Map<String, Integer> map1 = new TreeMap<>();
        // 间断倒序插入 100 个数
        int k =100;
        while (k-->0){map1.put(""+k, k);
        }
        // 查问
        for (String str :
                map1.keySet()) {
            // 这里会正序输入
            System.out.println(str);
        }
    }
}

输入如下所示:

仔细的你们,应该会发现下面的输入有点别致

那是因为这里的键 key(0~99) 其实不是整型,而是字符串类型,所以排序依照字符串的升序来排,才会呈现如图所示的后果

(倡议理论场景不要这样搞,容易出事,字符串尽量不要用纯数字,而是要跟字母做拼接;)

正确的做法是 key=“a”+i,这种形式

LinkedHashMapDemo.java


public class MapDemo {public static void main(String[] args) {
        // LinkedHashMap
        Map<String, Integer> map2 = new LinkedHashMap<>();
        // 倒序插入 100 个数
        int j =100;
        while (j-->0){map2.put("a"+j, j);
        }
        for (String str :
                map2.keySet()) {
            // 这里依照插入的程序顺次输入
            System.out.println(map2.get(str));
        }
    }
}

输入如下所示:

总结

Map 个别用到的有 HashMap,TreeMap,LinkedHashMap,当然还有并发相干的,这里入门级别的先不波及(比方 ConcurrentHashMap)

  • HashMap 的插入和拜访都很快,然而外部是无序排列
  • TreeMap 的插入和拜访都很慢,然而外部是有序排列,默认按 key 升序排列
  • LinkedHashMap 领有 HashMap 的大部分长处,而且还能够依照元素插入的程序来拜访元素,然而性能会比 HashMap 差

后记

最初,感激大家的观看,谢谢

正文完
 0