数组公式

HashMap 完全解析

回眸只為那壹抹淺笑 提交于 2019-12-16 23:39:08
HashMap 完全解析 1. 基本特点 2. 存储结构 2.1 HashMap 数据底层具体存储的是什么? 2.2 为什么要用单链表的方式? 3. HashMap 的成员变量 4. 确定数组索引位置的 hash 算法 4.1 为什么要采用这种算法呢? 番外: 为什么用 & 操作呢? 为什么可以使用位运算(&)来实现取模运算(%)呢 5. 存储数据的 put 方法 6. HashMap 的扩容机制 7. 为什么HashMap线程不安全? 7.1 多线程 put,导致的数据不一致。 7.2 resize 造成的无限循环 参考 1. 基本特点 HashMap 是 java 中用于映射(键值对)处理的数据类型。基于哈希表的 Map 接口的实现。最多只允许一条记录的键为 null,允许多条记录的值为 null。 HashMap 不保证映射的顺序。特别是, 它不能保证顺序会随着时间的推移保持恒定 。 HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度 O(1)。 2. 存储结构 从结构实现来讲,HashMap 是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的。 [图片上传失败…(image-7d8358-1576498907545)] 2.1 HashMap 数据底层具体存储的是什么? 通过查看 HashMap 的源码

面试3——java集合类总结(Map)

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-16 22:30:53
1.概述: Java 中的map集合使用键值对(key-value)来保持数据,其中值(value)可以重复,键(key)必须唯一,但最多只能有一个key为空,它的主要实现类有HashMap、HashTable、TreeMap、LinkedHashMap. Map集合方法摘要 map和collection的区别: map存储的是键值对形式的元素,键唯一,值可以重复 collection存储的是单列元素,子接口set元素唯一,子接口list元素可以重复 map集合的数据结构值针对键有效,跟值无关,collection集合的数据结构针对的是元素有效 map的遍历方式(4种) package Three; import java.util.*; public class Map_sort { public static void main(String[] args) { Map<String,String> map = new HashMap<String, String>(); map.put("a","@"); map.put("f","@"); map.put("n","@"); map.put("e","@"); map.put("q","@"); map.put("d","@"); map.put("l","@"); // 第一种遍历map的方法,通过加强for循环map

这些经典算法面试题你都不会的话,不要去应聘啦!

拈花ヽ惹草 提交于 2019-12-16 11:09:42
〖内容正文〗 1、一群 猴子 排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程 模拟 此过程,输入m、n, 输出最后那个大王的编号。 function king($n, $m){ $monkeys = range(1, $n); //创建1到n数组 $i=0; while (count($monkeys)>1) { //循环条件为猴子数量大于1 if(($i+1)%$m==0) { //$i为数组下标;$i+1为猴子标号 unset($monkeys[$i]); //余数等于0表示正好第m个,删除,用unset删除保持下标关系 } else { array_push($monkeys,$monkeys[$i]); //如果余数不等于0,则把数组下标为$i的放最后,形成一个圆形结构 unset($monkeys[$i]); } $i++;//$i 循环+1,不断把猴子删除,或 push到数组 } return current($monkeys); //猴子数量等于1时输出猴子标号,得出猴王 } echo king(6,3); 2、有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡

《吊打面试官》系列-HashMap

杀马特。学长 韩版系。学妹 提交于 2019-12-16 10:47:25
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 上已经收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。 前言 作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚( 请允许我使用一下夸张的修辞手法 )。 于是在一个寂寞难耐的夜晚,我痛定思痛,决定开始写互联网技术栈面试相关的文章,希望能帮助各位读者以后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂Offer! 所有文章的名字只是我的噱头,我们应该有一颗谦逊的心,所以希望大家怀着空杯心态好好学,一起进步。 正文 一个婀娜多姿,穿着衬衣的小姐姐,拿着一个精致的小笔记本,径直走过来坐在我的面前。 看着眼前这个美丽的女人,心想这不会就是Java基础系列的面试官吧,真香。 不过看样子这么年轻应该问不出什么深度的吧,嘻嘻。(哦?是么😏) 小伙子,听前面的面试官说了,你Redis和消息队列都回答得不错,看来还是有点东西。 美丽迷人的面试官您好,您见笑了,全靠看了敖丙的《吊打面试官》系列

被大厂面试官连环炮轰炸的ThreadLocal (吃透源码的每一个细节和设计原理)

走远了吗. 提交于 2019-12-15 01:32:40
引言 ThreadLocal 是面试过程中非常高频的一个类,这类的复杂程度绝对是可以带出一系列连环炮的面试轰炸。biu biu biu ~~~~. 一直觉得自己对这个类很了解了,但是直到去看源码,接二连三的技术浮出水面(弱引用,避免内存溢出的操作,开放地址法解决hash 冲突,各种内部类的复杂的关系),看到你怀疑人生,直到根据代码一步一步的画图才最终理解(所以本篇文章会有大量的图)。 这里也给大家一个启示,面对复杂的事情的时候,实在被问题绕晕了,就画图吧,借助图可以让问题可视化,便于理解。 WHAT ThreadLocal 是一个线程的本地变量,也就意味着这个变量是线程独有的,是不能与其他线程共享的,这样就可以避免资源竞争带来的多线程的问题,这种解决多线程的安全问题和lock(这里的lock 指通过synchronized 或者Lock 等实现的锁) 是有本质的区别的: lock 的资源是多个线程共享的,所以访问的时候需要加锁。 ThreadLocal 是每个线程都有一个副本,是不需要加锁的。 lock 是通过时间换空间的做法。 ThreadLocal 是典型的通过空间换时间的做法。 当然他们的使用场景也是不同的,关键看你的资源是需要多线程之间共享的还是单线程内部共享的 使用 ThreadLocal 的使用是非常简单的,看下面的代码 public class Test {

并发编程(十四)—— ScheduledThreadPoolExecutor 实现原理与源码深度解析 之DelayWorkQueue

六月ゝ 毕业季﹏ 提交于 2019-12-14 19:59:20
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 目录 什么是堆? 满二叉树 完全二叉树 堆的实现 最大堆的插入(ADD) 最大堆的删除(DELETE) DelayedWorkQueue类 属性 插入元素方法 等待获取队列头元素 超时等待获取队列头元素 推荐博客 总结 正文 我们知道线程池运行时,会不断从任务队列中获取任务,然后执行任务。如果我们想实现延时或者定时执行任务,重要一点就是任务队列会根据任务延时时间的不同进行排序,延时时间越短地就排在队列的前面,先被获取执行。 队列是先进先出的数据结构,就是先进入队列的数据,先被获取。但是有一种特殊的队列叫做优先级队列,它会对插入的数据进行优先级排序,保证优先级越高的数据首先被获取,与数据的插入顺序无关。 实现优先级队列高效常用的一种方式就是使用堆。 回到顶部 什么是堆? 堆通常是一个可以被看做一棵树的数组对象。 堆(heap)又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。 因为队列中允许的操作是先进先出(FIFO),在队尾插入元素,在队头取出元素。 而堆虽然在堆底插入元素,在堆顶取出元素,但是堆中元素的排列不是按照到来的先后顺序,而是按照一定的优先顺序排列的。 这里来说明一下满二叉树的概念与完全二叉树的概念。 满二叉树    除了叶子节点,所有的节点的左右孩子都不为空

Java HashMap工作原理

丶灬走出姿态 提交于 2019-12-14 16:36:41
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 内部存储 Java HashMap类实现了Map<K, V>接口。这个接口中的主要方法包括: V put(K key, V value) V get(Object key) V remove(Object key) Boolean containsKey(Object key) HashMap使用了一个内部类Entry<K, V>来存储数据。这个内部类是一个简单的键值对,并带有额外两个数据: 一个指向其他入口(译者注:引用对象)的引用,这样HashMap可以存储类似链接列表这样的对象。 一个用来代表键的哈希值, 存储这个值可以避免 HashMap在每次需要时都重新生成键所对应的哈希值。 下面是Entry<K, V>在Java 7下的一部分代码: 1 2 3 4 5 6 7 staticclassEntry<K,V>implementsMap.Entry<K,V> { finalK key; V value; Entry<K,V> next; inthash; … } HashMap将数据存储到多个单向Entry链表中(有时也被称为桶bucket或者容器orbins)。所有的列表都被注册到一个Entry数组中(Entry<K, V>[]数组),这个内部数组的默认长度是16。

Java HashMap工作原理【图文版】

て烟熏妆下的殇ゞ 提交于 2019-12-14 16:36:25
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 大部分Java开发者都在使用Map,特别是HashMap。HashMap是一种简单但强大的方式去存储和获取数据。但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.HashMap的大量源代码(包括Java 7 和Java 8),来深入理解这个基础的数据结构。在这篇文章中,我会解释java.util.HashMap的实现,描述Java 8实现中添加的新特性,并讨论性能、内存以及使用HashMap时的一些已知问题。 内部存储 Java HashMap类实现了Map<K, V>接口。这个接口中的主要方法包括: V put(K key, V value) V get(Object key) V remove(Object key) Boolean containsKey(Object key) HashMap使用了一个内部类Entry<K, V>来存储数据。这个内部类是一个简单的键值对,并带有额外两个数据: 一个指向其他入口(译者注:引用对象)的引用,这样HashMap可以存储类似链接列表这样的对象。 一个用来代表键的哈希值, 存储这个值可以避免 HashMap在每次需要时都重新生成键所对应的哈希值。 下面是Entry<K, V>在Java 7下的一部分代码: static class

深入浅出HashMap的设计与优化

空扰寡人 提交于 2019-12-13 00:50:09
一:常用的数据结构 众所周知, ArrayList 是基于数组的数据结构实现的,LinkedList 是基于链表的数据结构实现的,而 HashMap 是基于哈希表的数据结构实现的。我们不妨一起来温习下常用的数据结构。 数组: 采用一段连续的存储单元来存储数据。对于指定下标的查找,时间复杂度为 O(1),但在数组中间以及头部插入数据时,需要复制移动后面的元素。 链表: 一种在物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素)组成,结点可以在运行时动态生成。每个结点都包含“存储数据单元的数据域”和“存储下一个结点地址的指针域”这两个部分。由于链表不用必须按顺序存储,所以链表在插入的时候可以达到 O(1) 的复杂度,但查找一个结点或者访问特定编号的结点需要 O(n) 的时间。 哈希表: 根据关键码值(Key value)直接进行访问的数据结构。通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数,存放记录的数组就叫做哈希表。 树: 由 n(n≥1)个有限结点组成的一个具有层次关系的集合,就像是一棵倒挂的树。 二:HashMap 的实现结构 了解完数据结构后,我们再来看下 HashMap 的实现结构。作为最常用的 Map 类,它是基于哈希表实现的,继承了 AbstractMap

Java多线程进阶—— J.U.C之atomic框架:Atomic数组

十年热恋 提交于 2019-12-13 00:47:51
一、Atomic数组简介 Atomic数组,顾名思义,就是能 以原子的方式,操作数组中的元素 。 JDK提供了三种类型的原子数组: AtomicIntegerArray 、 AtomicLongArray 、 AtomicReferenceArray 。 这三种类型大同小异,AtomicIntegerArray对应AtomicInteger,AtomicLongArray对应AtomicLong,AtomicReferenceArray对应AtomicReference。 其实阅读源码也可以发现,这些数组原子类与对应的普通原子类相比,只是 多了通过索引找到内存中元素地址的操作 而已。 注意:原子数组并不是说可以让线程以原子方式一次性地操作数组中所有元素的数组。 而是指对于数组中的每个元素,可以以原子方式进行操作。 说得简单点, 原子数组类型 其实可以看成 原子类型组成的数组 。 比如: AtomicIntegerArray array = new AtomicIntegerArray(10); array.getAndIncrement(0); // 将第0个元素原子地增加1 等同于 AtomicInteger[] array = new AtomicInteger[10]; array[0].getAndIncrement(); // 将第0个元素原子地增加1 二