一、关于集合

1、数组,链表和哈希表(散列表)的存储方式

(1)传统的数组结构存储数据会在内存中开辟连续得空间,结合下标从而使得可以快速访问数据,但是删除和添加数据就很浪费资源



(2)链表不需要开辟连续空间,使用指针来指向数据,因此删除和添加操作比较快,但是查询数据需要遍历全部得元素



(3)而哈希表[散列表]结合两者得长处,合二为一。使得哈希表比较牛掰(初始容量,数组长度默认为16,分为单指针和双指针,双指针每个元素指向前面元素同时指向后面元素)



(4)Hash也称散列。基本原理就是把任意长度的输入,通过Hash算法变成固定长度得输出,这个映射得规则对应的就是Hash算法,而原始数据映射后得二进制串就是Hash值

entry----key----hash----index哈希值就是把各种类型的key算成统一的下标(.hashcode())

Hash特点
1、从Hash值不可反向推导出原始数据
2、输入数据的微小变化也会得到完全不同的hash值,相同的数据的道相同的hash值
3、哈希算法执行高效,长文本也能快速计算出哈希
4、Hash算法冲突概率较小 Hash表在jdk1.7中使用数组+链表 jdk1.8中加入了红黑树
由于Hash的原理是将 输入空间的值 映射成 hash空间内,而hash值空间远小于输入的空间。
根据抽屉原理,一定会存在不同的输入被映射成相同的输出。 抽屉原理:9个抽屉放10个苹果,怎么放都会有一个抽屉里有2个及以上的苹果

(5)HashMap的继承体系

二、HashMap

1、底层一些常量与属性和构造方法

常量:
//缺省大小
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 //数组的最大长度
static final int MAXIMUM_CAPACITY = 1 << 30; //缺省负载因子大小
static final float DEFAULT_LOAD_FACTOR = 0.75f; //树化阈值(链表长度超过8之后并且数组长度大于64就会升级成一个树了)
static final int TREEIFY_THRESHOLD = 8; //树降级成为链表的阈值(删除树中元素,元素=6降级为链表)
static final int UNTREEIFY_THRESHOLD = 6; //数组长度大于64(并且某个链表长度>8)升级为红黑树
static final int MIN_TREEIFY_CAPACITY = 64; 属性:
//Hash表,put时初始化
transient Node<K,V>[] table; //
transient Set<Map.Entry<K,V>> entrySet; //当前Hash表中元素个数
transient int size; //当前Hash表结构修改次数(插入元素或删除元素,替换不会计数)
transient int modCount; //扩容阈值(Hash表中元素超过阈值时触发扩容,超过阈值不扩容影响查找性能。链化严重)
int threshold; //负载因子(计算threshold = capacity数组长度 *loadFactor负载因子)
final float loadFactor; 构造方法:
//
public HashMap(int initialCapacity, float loadFactor) {
//做了逻辑校验
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
//传入数组长度超过最大长度就设置为最大长度
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
//负载因子<=0。。。。||不是数
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
//赋值负载因子
this.loadFactor = loadFactor;
//赋值扩容阈值 位移计算只能是2的次方数导致table的长度只能是2的次方
传过来init。。为7计算为8,9计算为16
this.threshold = tableSizeFor(initialCapacity);
} //设置默认负载因子
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

2、put源码分析

put方法时会默认(new entry(key,value,null=指针next))

public V put(K key, V value) {
//table的length不是特变长的情况下,让让key的hash值高于16位也参与路由运算
return putVal(hash(key), key, value, false, true);
} //实际用put向散列表插入数据
/**
* Implements Map.put and related methods
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent散列表存在欲插入的key就不插了(有就替换)
* @param evict
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) { //tab:引用当前HashMap的散列表
//p:表示当前散列表的元素
//n:表示散列表数组的长度
//i:表示路由寻址 结果 Node<K,V>[] tab; Node<K,V> p; int n, i; //第一次插入数据时才会初始化,只是new出来并不会初始化(好多new出来但并不用)
//延迟初始化逻辑
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length; //寻址找桶位,刚好为null,这时直接将当前key-value转成node塞进去
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}

java数组 简单了解的更多相关文章

  1. java————数组 简单写出一个管理系统

    数组的特点 1,  数组是一块连续的空间,下标描述空间的位置. 2,  下标从0开始,最大下标为数组长度—1.(*.length-1) 3,  数组元素都是变量.(就是每个下标对应的内容).变量的类型 ...

  2. java数组简单逻辑代码

    package cuteSnow; public class HelloWorld { // 遍历数组里面的每个数字 public static void print(int[] array){ St ...

  3. 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化

    序列化在高性能网络编程.分布式系统开发中是举足轻重的之前有用过Java序列化.ProtocolBuffer等,在这篇文章这里中简单分析序列化后的byte数组观察各种序列化的差异与性能,这里主要分析Ja ...

  4. Java数组你知多少?

    下面我带大家一起加深一下对Java数组的认识: 1.理解数组 数组也是一种数据类型,本身就是一种引用类型,我们从它的初始化方法,通过关键字new去完成定义及初始化就可以知道. 数组的长度是不变的,一旦 ...

  5. 对java数组的一些理解

    刚开始学习Java的时候一直搞不清除获取数组的长度是用length()还是length,现在不妨来深入了解一下数组的真实面目. 我们不妨来看一下数组的源码,诶,数组的类名叫什么?我们声明一个int数组 ...

  6. Java开发知识之Java数组

    Java开发知识之Java数组 一丶数组简介 首先,不管是Java 还是 C++ 还是其它语言.都有数组. (有可能叫法不同) 数组简而言之就是存储一段连续相同数据类型的数据结构 在Java中数组可以 ...

  7. java 数组复制

    http://www.cnblogs.com/zhengbin/p/5671403.html http://www.cnblogs.com/jjdcxy/p/5870524.html Java数组拷贝 ...

  8. Java数组操作十大方法 (转)

    定义一个Java数组 String[] aArray = new String[5]; String[] bArray = {"a","b","c&q ...

  9. 1.1使用java数组,并开始封装我们自己的数组

    今天感冒了,全身酸软无力,啥样不想做,就来学习吧,此节我们从初步使用java中提供的数组,然后分析相关情况,过渡到封装我们自己的数组. 一.我们先来感受一下java提供的数组,以整型数组(int[]) ...

随机推荐

  1. linux中的gtk 编程的页面切换

    在我们使用gtk这个工具时,有时想在同一个窗口中,根据选择来显示不同的操作菜单,这篇博文主要是解决此类问题 //创建窗口 GtkWidget *CreateMenuMain() { GtkWidget ...

  2. C++覆盖,隐藏,重载

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  3. Announcing cnblogs-hardening 1.0 Preview 1

    Release Notes Write about coding Note About coding Share about coding Talk about coding Comment abou ...

  4. PAT (Advanced Level) Practice 1041 Be Unique (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1041 Be Unique (20 分) 凌宸1642 题目描述: Being unique is so important to peo ...

  5. 利用Vue实现一个简单的购物车功能

    开始学习Vue的小白,dalao多多指正 想要实现下面这个界面,包含总价计算.数量增加和移除功能 话不多说代码如下 <!DOCTYPE html> <html> <hea ...

  6. c# 输出一个数组

    关于C#输出一个数组最普遍的方法就是用for 循环语句写 如: int[] a = new int[10];for (int i = 0; i < a.Length; i++) { a[i] = ...

  7. manjaro配置攻略

    2021.1.30 更新 1 概述 本文主要讲述了新安装的Manjaro一些常用的配置,包括源.常用软件.快捷键.终端以及一些效率工具的配置. 2 pacman源 首先是pacman源的选择: sud ...

  8. 源码编译安装MySQL8.0.20

    1 概述 本文章主要讲述了如何从源码编译安装MySQL社区版8.0.20,首先会介绍一些编译安装的相关知识,然后开始编译安装 2 源码编译安装的相关知识 2.1 make与configure make ...

  9. shell脚本 5 sed和awk

    文本处理三剑客 在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具: 命令 描述 grep 默认不支持扩展表达式,加-E 选项开启 ERE.如果不加-E 使用花括号要加转义符\{\} ...

  10. Day09_42_Set集合_HashSet

    集合之HashSet * HashSet - HashSet无序不可重复,HashSet底层实际上是一个HashMap,HashMap底层采用了Hash表数据结构. - 哈希表又叫做散列表,哈希表底层 ...