一、关于集合

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. 为什么数据库字段要使用NOT NULL?

    最近刚入职新公司,发现数据库设计有点小问题,数据库字段很多没有NOT NULL,对于强迫症晚期患者来说,简直难以忍受,因此有了这篇文章. 基于目前大部分的开发现状来说,我们都会把字段全部设置成NOT ...

  2. Nginx错误日志(error_log)配置及信息详解

    Nginx错误日志信息介绍 Nginx的错误信息是调试Nginx服务的重要手段,属于核心功能模块(ngx_core_module)的参数,该参数的名字为error_log,可以放在Main区块中全局配 ...

  3. matplotlib安装问题解决

    p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-c ...

  4. OO第一单元作业——魔幻求导

    简介 本单元作业分为三次 第一次作业:需要完成的任务为简单多项式导函数的求解. 第二次作业:需要完成的任务为包含简单幂函数和简单正余弦函数的导函数的求解. 第三次作业:需要完成的任务为包含简单幂函数和 ...

  5. C程序数组算法 — 冒泡法排序【前冒 || 后冒】

    第一种写法(前冒泡): /* C程序数组算法 - 冒泡法排序 * 此例子按照 大 -> 小 排序 * 原理:两两相比较,然后进行大小对调 * 比较次数: n^2 次 * 说明:冒泡排序是相对稳定 ...

  6. Toolkit 大更新:UI 更美观,用起来更方便!

    前言 前段时间有小伙伴在群里聊天,说到 Toolkit 下载量到 4.9k 了.就突然想起来,很久没有更新这个插件. PS:我是用它申请了 License,一般时候使用 Json 格式化功能. 趁着周 ...

  7. JWT 介绍 - Step by Step

    翻译自 Mohamad Lawand 2021年3月11日的文章 <Intro to JWT - Step by Step> [1] 在本文中,我将向您介绍 JWT[2]. 我们今天要讲的 ...

  8. Object o = new Object()占多少个字节?-对象的内存布局

    一.先上答案 这个问题有坑,有两种回答 第一种解释: object实例对象,占16个字节. 第二种解释: Object o:普通对象指针(ordinary object pointer),占4个字节. ...

  9. day-4 xctf-pwn CGfsb

    xctf-pwn CGfsb 传送门:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id= ...

  10. JavaScript 简写技巧

    1. 声明变量 //普通写法 let x; let y = 20; //简写 let x, y = 20; 2. 给多个变量赋值 //普通写法 let a, b, c; a = 5; b = 8; c ...