Java Se :Map 系列
之前对Java Se中的线性表作了简单的说明。这一篇就来看看Map。
Map系列的类,并不是说所有的类都继承了Map接口,而是说他们的元素都是以<Key, Value>形式设计的。
Dictionary
这个类现在不推荐使用了,但也有必要说一下,在它的描述中,有这么一句:Any non-null object can be used as a key and as a value。
现在都改用Map接口了。
Map
这个接口用于替换Dictionary的。这种集合提供了三种视图方式:
1)a set of keys
2)collection of Values
3)set of Entry<key, value>
Hashtable
这个类继承了Dictionary实现了Map。下面就重点看看这个类如何实现。

从这里看Hashtable是一个数组,数组的元素是Entry。
在看看Entry的设计:

这个Entry是一个单链表。
所以Hashtable的数据结构就可以认为是这样的:

为什么会这样设计?
以为硬件的原因,支持数组和链表两种形式,所以其他的数据结构(集合)都是基于这两类基础结构实现的。
Hashtable的设计,关键一点是hash,它计算的是key的hash,通过key的hashcode来计算这个元素所在的单链表在数组中的索引,然后根据索引取到单链表,然后进行其他的操作。
接下来看看它的几个重要方法如何实现:
put
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// 如果key已经在这个hashtable中存在,就覆盖原有的value,并返回原有的value。
// 从这一小段代码中,我们就可以看出hashtable的结构确实如上面所想的那样。
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 如果不存在,就把key value 封装成一个Entry,然后插入到相应位置
// 在之前的代码中已经计算出它的索引了,接下来的任务就是把entry插入到数组索引位置处的单链表里。插入的时候是从头部插入的。
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
Hashtable#put(key, value)
常用的方法get(key),remove(key)的方法就不分析了,因为没有必要,只要你了解了这个数据结构,自己就可以实现它的几个常用的方法。
keys


拿到的结果其实是一个枚举器(不过这个枚举器比较特殊,实现了Enumeration接口和Iterable接口),并不是一个集合。
同样的道理,elements也是如此,拿到的结果是一个遍历value的枚举器。
HashMap
HashMap的存储结构如下图所示,因为源码部分太多,所以就截了这么一张图,但也足够说明问题了:

从图上很容易看出,HashMap也是使用了数组实现的,数组中的元素是Node,再看看Node的设计:

Node也是一个单链表,看来HashMap与Hashtable在结构上是基本一致的。
也就是说他的模型也是下面图中所示:

如果说HashMap的结构只是这个样子的话,就没有必要存在了。为什么这么说呢,关键点还是在Node上,看看他的两个子类:

Entry:
每个节点又添加了一两个引用:before,after,这样一来结构就可以猜想为:

但其实并不是这个样子的,会根据hashcode进行一些算法处理,形成链式结构,也就是LinkedHashMap了。
如果有兴趣可以了解一些LinkedHashMap是如何实现的。
TreeNode:

每个节点都可以是一个树。就让结构变得更为复杂了。
Java Se :Map 系列的更多相关文章
- Java Se 基础系列(笔记) -- OO
记录所学到的关于Java Se的一些基础知识 1.对象是通过“属性(成员变量)”和“方法”来分别对应事物所具有的静态属性和动态属性 2.类(Class)是对某一类事物的抽象,对象(Object)为某个 ...
- Java Se 基础系列(笔记) -- Exception && Array
Exception 1.java 异常是java提供的用于处理程序中错误(指在程序运行的过程中发生的一些异常事件)的一种机制 2.java程序的执行过程中如果发生异常事件则自动生产一个异常类对象,该对 ...
- Java Se 基础系列(笔记) -- BasicDataType
java.lang.String类代表不可变的字符序列 String类常用方法:1.public char charAt(int index); -- 返回下标为index的字符 2.public i ...
- Java SE开发系列-JDK下载安装
JDK下载安装 JDK是Java的开发环境,目前JDK内部也包含了JRE,JRE主要是JAVA程序的运行环境. 点击官方下载地址,按着下图操作即可下载对应系统的不同版本JDK. 进入页面滑到页面底部点 ...
- 4.Java集合总结系列:Map接口及其实现
一.Map接口 Map集合的特点是:通过key值找到对应的value值,key值是唯一的,value可以重复.Map中的元素是无序的,但是也有实现了排序的Map实现类,如:TreeMap. 上面Map ...
- Java SE之For增强与Iterator遍历器提取数据(附Map.Entry)
增强for循环: 1.操作数组 2.操作List集合 3.操作Map集合 1.map.values()法 2.map.keySet()法 [传统方法] 3.Map.Entry法 ...
- java se系列(十二)集合
1.集合 1.1.什么是集合 存储对象的容器,面向对象语言对事物的体现,都是以对象的形式来体现的,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式.集合的出现就是为了持有对象.集 ...
- java se系列(一)开发前奏
1. 软硬件知识 电子计算机:俗称电脑,是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机 cpu:是一台计算机的运算核心和控制核 ...
- Java SE 9 新增特性
Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
随机推荐
- 职责链模式(chain of responsibility)
一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所 ...
- 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)
原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...
- 点我吧工作总结(技术篇) zookeeper
我思故我在,提问启迪思考! 1.什么是zookeeper? 2.zookeeper与dubbo.springMVC之间的协同工作? http://doc.okbase.net/congcong68/a ...
- 容器--WeakHashMap
一.概述 WeakHashMap是Map的一种,根据其类的命令可以知道,它结合了WeakReference和HashMap的两种特点,从而构造出了一种Key可以自动回收的Map. 前面我们已经介绍了W ...
- strtr和str_replace字符替换函数
(一)strtr是字符替换函数 (1)单个字符替换: <?php echo strtr("abba", "ab", "10"),&qu ...
- C语言Scanf函数
C语言的scanf函数 一.变量的内存分析 (一)字节与地址 ①. 内存以字节为单位 每个字节都有自己的内存地址,根据地址就可以找到该字节.整个内存相当于一整个酒店,而酒店以房间为单位,在这里每个房间 ...
- Guava学习笔记:Guava新增集合类型-Multimap
在日常的开发工作中,我们有的时候需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,以便做相应的业 ...
- linux常用命令之查阅文件
CAT cat – concatenate print files 连续的输出文件内容 用法 cat [-nbA] file 选项 -n line number 输出行号 -b line number ...
- IoC和DI的理解
1 概述 当我们想闭上眼睛想如何让我们的软件更加可用可维护时,我们总能想到一个词:松耦合.在这篇文章中,主要讲述了模块间存在的依赖关系,但这种依赖关系违背了依赖倒置原则.在这之后,我们将讨论一种解除软 ...
- 使用React并做一个简单的to-do-list
1. 前言 说到React,我从一年之前就开始试着了解并且看了相关的入门教程,而且还买过一本<React:引领未来的用户界面开发框架 >拜读.React的轻量组件化的思想及其virtual ...