| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Java面试题十四:HashMap,android性能优化面试 -> 正文阅读 |
|
[移动开发]Java面试题十四:HashMap,android性能优化面试 |
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } 3、什么情况下转为红黑树,代码体现? ================== ![](https://img-blog.csdnimg.cn/20210512185332108.png?x-oss-pro
cess=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Nvbmd6aTEyMjg=,size_16,color_FFFFFF,t_70) 代码体现: static final int TREEIFY_THRESHOLD = 8; final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { … if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } … } 4、红黑树有什么特性?红黑树的时间复杂度是多少?理想中的HashMap的时间复杂度是多少? ============================================= 4.1、红黑树有什么特性? 4.2、红黑树的时间复杂度是多少? 4.3、理想中的HashMap的时间复杂度是多少? O(logN) 其他面试题: 1. HashMap的底层原理是什么?线程安全么? 百度 美团 2. HashMap中put是如何实现的? 滴滴 4. 什么是哈希碰撞?怎么解决? 滴滴 美团 5. HashMap和HashTable的区别 小米 6. HashMap中什么时候需要进行扩容,扩容resize()是如何实现的? 滴滴 7. hashmap concurrenthashmap原理 美团 8. arraylist和hashmap的区别,为什么取数快?字节跳动 5、HashMap的底层原理是什么?线程安全么? ======================== https://blog.csdn.net/songzi1228/article/details/99974540 HashMap底层是数组+链表,链表数据超过8个转为红黑树。不是线程安全的。作为对比,HashTable是线程安全的,因为HashTable对外提供的方法都加上了synchronized。 6、谈一下hashMap中什么时候需要进行扩容,扩容resize()又是如何实现的? ========================================== /**
*/ static final float DEFAULT_LOAD_FACTOR = 0.75f; /**
*/ int threshold; // threshold 赋值 final Node<K,V>[] resize() { … newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); threshold = newThr; … } final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { … if (++size > threshold) resize(); … } threshold??[?θre?ho?ld]? 门槛。 有一个threshold的参数,一旦HashMap的size超过threshold就会触发扩容。 那么?resize的代码里又有什么逻辑呢? 参照咕泡学院公开课Jack老师??https://www.bilibili.com/video/av75970633。时间 1:04:10左右 /**
*/ final Node<K,V>[] resize() { Node<K,V>[] oldTab = table; int oldCap = (oldTab == null) ? 0 : oldTab.length; int oldThr = threshold; int newCap, newThr = 0; if (oldCap > 0) { if (oldCap >= MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return oldTab; } // newCap = oldCap << 1 容量在这里进行扩容,翻倍 else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) newThr = oldThr << 1; // threshold同时也进行扩容 } else if (oldThr > 0) // initial capacity was placed in threshold newCap = oldThr; else { // zero initial threshold signifies using defaults newCap = DEFAULT_INITIAL_CAPACITY; newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); } if (newThr == 0) { float ft = (float)newCap * loadFactor; newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? (int)ft : Integer.MAX_VALUE); } threshold = newThr; @SuppressWarnings({“rawtypes”,“unchecked”}) Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap]; table = newTab; // 扩容后,把oldTab的数据复制到newTab中 // 专业术语叫做重新散列。大白话:把旧数组中的Node对象移动到新数组中 if (oldTab != null) { for (int j = 0; j < oldCap; ++j) { Node<K,V> e; if ((e = oldTab[j]) != null) { oldTab[j] = null; //a.只有一个元素 if (e.next == null) newTab[e.hash & (newCap - 1)] = e; //c.它下面有红黑树 else if (e instanceof TreeNode) ((TreeNode<K,V>)e).split(this, newTab, j, oldCap); //b.它下面有链表 else { // preserve order Node<K,V> loHead = null, loTail = null; Node<K,V> hiHead = null, hiTail = null; Node<K,V> next; do { next = e.next; if ((e.hash & oldCap) == 0) { if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null); if (loTail != null) { loTail.next = null; newTab[j] = loHead; } if (hiTail != null) { hiTail.next = null; newTab[j + oldCap] = hiHead; } } } } } return newTab; } 第一步,newCap = oldCap << 1 容量在这里进行扩容,翻倍;threshold也扩容,翻倍; 第二步,?扩容后,把oldTab的数据复制到newTab中。?专业术语叫做 重新散列。大白话:把旧数组中的Node对象移动到新数组中。 Node对象移动过程: 1.遍历数组下标(不为空的) 2.数组下标有元素,不为空 a.只有一个元素 b.它下面有链表 c.它下面有红黑树 7、什么是哈希碰撞?怎么解决? =============== 哈希碰撞又叫做哈希冲突。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 7:19:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |