Java学习笔记(二二)——Java HashMap

时间:2022-09-16 23:56:03

【前面的话】

早上起来好瞌睡哈,最近要注意一样作息状态。

      HashMap好好学习一下。

【定义】

  1. Hashmap是一个散列表,它存储的内容是键值对(key——value)映射。允许null值和null键。
  2. java.lang.Cloneable 接口是一个空接口,该接口用来指明一个对象是否可以进行克隆.实现了该接口的对象可以调用clone()方法来进行对象的浅克隆.  java默认的克隆是浅克隆,浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象.
  3. Serializable序列化接口,表明这个类可以进行序列化。
  4. Java HashMap的代码:

HashMap继承了AbstracMap类,实现了Map接口和Cloneable接口,以及Serializable接口。

1)  HashMap:

 public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

2)  AbstractMap

 public abstract class AbstractMap<K,V> implements Map<K,V> 

3)  Map

 public interface Map<K,V>

4)  Cloneable

 public interface Cloneable { //空接口
}

5)  Serializable

 public interface Serializable {//空接口
}

【知识点】

一、HashMap的数据结构

java中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本的结构来构造的,hashMap也不例外。Hashmap实际上是一个“链接散列”的数据结构,也就是数组和链表的结合体。

从下图可以看出,HashMap底层是一个数组结构,数组中的每一项又是一个链表,当新建一个HashMap的时候,就会初始化一个数组。

如下:

Java学习笔记(二二)——Java HashMap

源代码如下:

 static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
•••
}

可以看出,这就是java泛型的一个使用。就是一个key-value对,并且拥有指向下一个Entry的next,这就构成了一个链表。并且是一个单项链表。

二、HashMap的构造函数

 public HashMap(int initialCapacity, float loadFactor) 

指定容器大小和加载因子的构造函数

 public HashMap(int initialCapacity)

指定容器大小的构造函数,加载因子默认为0.75

 public HashMap() 

默认构造函数,构造一个默认初始容量为16,默认加载因子为0.75的空HashMap

 public HashMap(Map<? extends K, ? extends V> m) 

构造一个映射关系与指定Map相同的新的HashMap

三、HashMapAPI

类型

函数和功能

void

clear()

从此映射中移除所有映射关系。

Object

clone()

返回此 HashMap 实例的浅表副本:并不复制键和值本身。

boolean

containsKey(Object key)

如果此映射包含对于指定键的映射关系,则返回 true

boolean

containsValue(Object value)

如果此映射将一个或多个键映射到指定值,则返回 true

Set<Map.Entry<K,V>>

entrySet()

返回此映射所包含的映射关系的 Set 视图。

V

get(Object key)

返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null

boolean

isEmpty()

如果此映射不包含键-值映射关系,则返回   true

Set<K>

keySet()

返回此映射中所包含的键的 Set 视图。

V

put(K key, V value)

在此映射中关联指定值与指定键。

void

putAll(Map<? extends K,? extends V> m)

将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系。

V

remove(Object key)

从此映射中移除指定键的映射关系(如果存在)。

int

size()

返回此映射中的键-值映射关系数。

Collection<V>

values()

返回此映射所包含的值的 Collection 视图。

四、HashMap 的实例有两个参数影响其性能:初始容量加载因子

1. 容量是哈希表中数组的长度。初始容量只是哈希表在创建时的长度默认为16

 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

2. 加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。默认加载因子是 0.75,

  static final float DEFAULT_LOAD_FACTOR = 0.75f;

五、HashMapresizerehash

  1. 为什么会有初始容量和加载因子的设置,原因就是:当HashMap中的元素越来越多的时候,Hash冲突的几率也就会越来越高,也为数组的长度是默认固定的,为16。为了提高查询效率就需要对Hashmap的数组进行扩容,对hashmap进行扩容以后,最消耗性能的地方也就出现了,原数组中的数据必须进行重新计算放到新数组中去。这就是resize。
  2. 默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。

六、Hashmap的实现不是同步的,这意味着它不是线程安全的。它的key,value都可以为null。此外,HashMap中的映射不是有序的。

  1. HashMap不是线程安全的意思是多个线程操作的时候,结果可能不可预料,在操作系统中我们学习过,线程的安全状态是绝对安全的,不安全状态是可能会出现不安全的现象,如死锁,但有可能不会出现。
  2. HashMao的映射不是有序的,如下拉链法的例子:

在有拉链法建立散列表的时候,最终建立的散列表和最初的关键字码中的顺序是不一样的。

关键字码为:{06,12,15,26,36,38,41,44,51,68},散列函数为H(key)=key%13。用拉链法处理冲突建立的表如下:

Java学习笔记(二二)——Java HashMap

【参考资料】

1. 深入Java集合学习系列:HashMap的实现原理

2. Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例 (推荐这篇文章)

http://www.cnblogs.com/skywang12345/p/3310835.html

3. HashMap的工作原理

http://www.importnew.com/7099.html

【后面的话】

好好学习。

——TT

Java学习笔记(二二)——Java HashMap的更多相关文章

  1. 【Java学习笔记之二十六】深入理解Java匿名内部类

    在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...

  2. Java学习笔记心得——初识Java

    初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...

  3. 2019暑假Java学习笔记(二)

    目录 基础语法(下) 流程控制 if语句 switch语句 while语句和do-while语句 for语句 break关键字 continue关键字 数组 一维数组 二维数组 用户输入操作 练习题: ...

  4. Java学习笔记(二)&mdash&semi;&mdash&semi;变量与常量

    一.java中的关键字 Java 语言中有一些具有特殊用途的词被称为关键字.关键字对 Java 的编译器有着特殊的意义,在程序中应用时一定要慎重哦!! 二.认识Java标识符 1.定义 标识符就是用于 ...

  5. Java学习笔记(二)——Java操作properties文件

    [前面的话] 前段时间在学习和玩java web相关的东西,对于这些技术,一边学习,一边做东西,一边总结,希望可以一边成长和有所收获.有时总是思考太多反而成为了前进的阻力,所以对于生活还是简单一些,不 ...

  6. 【Java学习笔记之二十八】深入了解Java8新特性

    前言: Java8 已经发布很久了,很多报道表明java8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java 8 ...

  7. JAVA学习笔记(二):eclipse智能提示(转)

    存盘 Ctrl+s(肯定知道)注释代码 Ctrl+/取消注释 Ctrl+\(Eclipse3已经都合并到Ctrl+/了)代码辅助 Alt+/快速修复 Ctrl+1代码格式化 Ctrl+Shift+f整 ...

  8. Java学习笔记(二)不定时更新

    Java语言画图 package cn.witksy.dev; import javax.imageio.ImageIO; import java.awt.*; import java.awt.ima ...

  9. java学习笔记(二)图形用户接口

    这个学期主要放在ACM比赛上去了,比赛结束了.不知不觉就15周了,这周就要java考试了,复习一下java吧.java的学习的目的还是让我们学以致用,让我们可以运用java开发一下小项目.而不是单单应 ...

  10. 零基础学Java之Java学习笔记(二):Java快速入门

    提出要求: 开发一个 HelloWorld.java 程序,可以输出 "Hello,world!" 开发步骤: (1)将 Java 代码编写到扩展名为 HelloWorld.jav ...

随机推荐

  1. Java中的递归运算

    Java中的递归运算是一种在自己的方法内部调用自己的方法 递归的设计思想是:把一个复杂的问题,分解为若干个等同的子问题,重复执行,直到之问题能够简单到直接求解,这样复杂的问题就得以解决. 递归运算有两 ...

  2. javascript练习-扑克牌

    下面用枚举类型来实现一副扑克牌的类: //定义一个玩牌的类 function Card(suit,rank){ function inherit(p){ if(p==null) throw TypeE ...

  3. iOS计算字符串的宽度高度

    OC开发中会遇到根据字符串和字体大小来算计算出字符串所占的宽高->> 封装方法如下: #import <Foundation/Foundation.h> #import &lt ...

  4. 学习&quot&semi;大众点评网的架构设计与实践&quot&semi;

    今天看了一篇"程序员"上的文章:"大众点评网的架构与实践",因为里面谈的架构演变之路中所经历的痛点对我的工作经验来说感同身受,所以觉得文章里的一些解决方案对我还 ...

  5. cxGrid使用汇总(一)

    1. 去掉cxGrid中台头的Box 解决:在tableview1的ptionsview的groupbybox=false; 2.统计功能 解决:(1) tableview 1. tableview1 ...

  6. python:执行一个命令行N次

    经常希望可以执行一个命令行N次...windows下没有现成的工具(有?推荐给我!) 用python写一个... #!/usr/bin/evn python #coding: utf-8 " ...

  7. ACCESS数据库C&num;操作类(包含事务)

    转自http://blog.csdn.net/allen3010/article/details/6336717 这个是针对ACCESS数据库操作的类,同样也是从SQLHELPER提取而来,分页程序的 ...

  8. java中的特殊字符集合

    JAVA中转义字符: 1.八进制转义序列:\ + 1到3位5数字:范围'\000'~'\377'       \0:空字符 2.Unicode转义字符:\u + 四个 十六进制数字:0~65535   ...

  9. 你用&period;NET开发APP时,在云平台打包APP要填个&OpenCurlyDoubleQuote;包名”的含义

    ios 在ios平台,包名有它专有的名词:bundle ID.bundle ID可以翻译成包ID,也可以叫APP ID或者应用ID,他是每一个ios应用的全球唯一标识,只要bundle id不变,无论 ...

  10. 对于在git上面拉代码报&quot&semi;error&colon; RPC failed&semi; curl 56 OpenSSL SSL&lowbar;read&colon; SSL&lowbar;ERROR&lowbar;SYSCALL&comma; errno 10054&quot&semi;解决方法

    主要原因是安全设置的问题: 首先执行git config http.sslVerify "false"   若出现下列错误 git config http.sslVerify &q ...