美文网首页
Java核心技术-映射

Java核心技术-映射

作者: Tu9oh0st | 来源:发表于2018-12-19 21:48 被阅读0次

集是一个集合,它可以快速地查找现有的元素。但是,要查看一个元素,需要有要查找元素的精确副本。这不是一种非常通用的查找方式。通常,我们知道某些键的信息,并想要查找与之对应的元素。映射(map)数据结构就是为此设计的。映射用来存放键/值对。如果提供了键,就能够查找到值。

基本映射操作

Java类库为映射提供了两个通用的实现:HashMap和TreeMap。这两个类都实现了Map接口。

散列映射对键进行散列,树映射用键的整体顺序对元素进行排序,并将其组织成搜索树。散列或比较函数职能作用于键。于键关联的值不能进行散列或比较。

散列稍微快一些,如果不需要按照排序顺序访问键,就最好选择散列。

下列代码将为存储的员工信息建立一个散列映射:

Map<String, Employee> staff = new HashMap<>(); // HashMap implements Map
Employee harry = new Employee("Harry Hacker");
staff.put("987-98-9996", harry);

每当往映射中添加对象时,必须同时提供一个键。在这里,键是一个字符串,对应的值是Employee对象。

要想检索一个对象,必须使用(因而,必须记住)一个键。

String id = "987-98-9996";

e = staff.get(id);

如果在映射中没有与定键对应的消息,get将返回null。null返回值可能并不方便。有时可以有一个好的默认值,用作为映射中不存在的键。然后使用getOrDefault方法。

Map<String, Integer> scores = ...;

int score = scores.get(id,0); // Gets 0 if the id is not present

键必须是唯一的。不能对同一个键存放两个值。如果对同一个键两次调用put方法,第二个值就会取代第一个值。实际上,put将返回用这个键参数存储的上一个值。

remove方法用于从映射中删除给定键对应的元素。size方法用于返回映射中的元素数。

要迭代处理映射的键和值,最容易的方法是使用forEach方法。

更新映射项

处理映射时的一个难点就是更新映射项。正常情况下,可以得到与一个键关联的原值,完成更新,再放回更新后的值。不过,必须考虑一个特殊情况,即键第一次出现。下面来看一个例子,使用一个映射统计一个单词再文件中出现的频度。看到单词(word)时,我们将计数器增1,如下所示:

counts.put(word, counts.get(word) + 1)

这是可以的,不过一种情况除外:就是第一次看到word时。在这种情况下,get会返回null,因此会出现NullPointerException异常。

作为一个简单的补救,可以使用getOrDefault方法:

counts.put(word, counts.getOrDefault(word, 0) + 1);

另一个方法是首先调用putIfAbsent方法。只有当键原先存在时才会放入一个值。

counts.putInfAbsent(word, 0 );

counts.put(word,counts.get(word) + 1);

不过还可以做得更好。merge方法可以简化这个常见的操作。如果键原先不存在,下面的调用:

counts.merge(word, 1,Integer::sum);

将把word与1关联,否则使用Integer::sum函数组合原值和1(也就是将原值与1求和)。

映射视图

集合框架不认为映射本身是一个集合。(其他数据结构框架认为映射是一个键/值对集合,或者是由键索引的值集合。)

弱散列映射

设计WeakHashMap类是为了解决一个有趣的问题。如果有一个值,对应的键已经不再使用了,将会出现什么情况呢?

首先,垃圾回收器跟踪活动的对象。只要映射对象是活动的,其中的所有桶也是活动的,它们不能被回收。

WeakHashMap使用弱引用(weak references)保存键。WeakReference对象将引用保存到另外一个对象中,在这里,就是散列键。对于这种类型的对象,垃圾回收器用一种特有的方式进行处理。通常,如果垃圾回收器发现某个特定的对象已经没有他人引用了,就将其回收。然而,如果某个对象只能由WeakReference引用,垃圾回收器仍然回收它,但要将引用这个对象的弱引用放入队列中。WeakHashMap将周期性地检查队列,以便找出新添加地弱引用。一个弱引用进入队列意味着这个键不再被他人使用,并且已经被收集起来。于是,WeakHashMap将删除对应的条目。

链接散列集与映射

链接散列映射将用访问顺序,而不是插入顺序,对映射条目进行迭代。每次调用get或put,受到影响的条目将从当前的位置删除,并放到条目链表的尾部(只有条目在链表中的位置会受影响,而散列表中的桶不会受影响。一个条目总位于与键散列码对应的桶中)。

访问顺序对于实现高速缓存的“最近最少使用”原则十分重要。

枚举集与映射

EnumSet是一个枚举类型元素集的高效实现。由于枚举类型只有有限个实例,所以EnumSet内部用位序列实现。如果对应的值在集中,则相应的位被置为1。

EnumMap是一个键类型为枚举类型的映射。他可以直接且高效地用一个值数组实现。

标识散列映射

类IdentityHashMap有特殊的作用。在这个类中,键的散列值不是用hashCode函数计算的,而是用System.identityHashCode方法计算的。这是Object.hashCode方法根据对象的内存地址类计算散列码所使用的方式。而且,在对两个对象进行比较时,IdentityHashMap类使用==,而不是用equals。

也就是说,不同的键对象,即使内容相同,也被视为是不同的对象。在实现对象遍历算法(如对象串行化)时,这个类非常有用,可以用来跟踪每个对象的遍历状况。

相关文章

  • Java核心技术-映射

    集是一个集合,它可以快速地查找现有的元素。但是,要查看一个元素,需要有要查找元素的精确副本。这不是一种非常通用的查...

  • Java 语言原理

    Java核心技术讲解学习一 Java核心技术讲解学习二 Java核心技术讲解学习三 Java核心技术讲解学习四 J...

  • 双11Java程序员书单推荐

    Java 《Java核心技术卷I》 《Java核心技术卷II》 《Java编程思想》 《Java并发编程实战》 《...

  • # [Java学习]1.Java基础【学习笔记】

    [Java学习]1.Java基础【学习笔记】 书籍 《Java核心技术》、《Java核心技术精讲》 2018-09...

  • Java核心知识

    Java核心语法 作者:springremember 书籍:《Java核心技术卷一》《Java核心技术卷二》 ja...

  • 记录一些书籍

    JAVA 基础 《Java核心技术·卷1:基础知识》《Java核心技术 卷2:高级特性》《Java8 实战》 并发...

  • Java SE基础部分

    Java核心语法 书籍:《Java核心技术卷一》《Java核心技术卷二》 java包结构:核心包,Java1一同出...

  • java修炼书籍

    1,《java核心技术(卷1)》 2,《java核心技术(卷1)》 3, 《java学习指南(第四版)》 4,《e...

  • 学习java的书籍

    Java基础部分 [JAVA核心技术 Head First Java 重构 Effective java 中文版(...

  • Java架构师阅读书单

    一、内功心法 Java基础: 《Java核心技术》《Java编程思想》《Effective Java》 多线程...

网友评论

      本文标题:Java核心技术-映射

      本文链接:https://www.haomeiwen.com/subject/ywyskqtx.html