文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。
相关文章:
- LeetCode:55. Jump Game(跳远比赛)
- Leetcode:300. Longest Increasing Subsequence(最大增长序列)
- LeetCode:560. Subarray Sum Equals K(找出数组中连续子串和等于k
JDK 8 对 HashMap
进行了重要优化,特别是在处理大量键值冲突时,提升了性能和效率。这些优化主要集中在以下几个方面:
1. 树形化(Treeification)
- 在 JDK 8 之前,
HashMap
的底层实现是数组加链表的结构。当多个键哈希值相同(即哈希冲突)时,这些键值对会被存储在同一个链表中。如果冲突较多,链表变长,HashMap
的查找、插入和删除操作的时间复杂度会退化到 O(n)。 - JDK 8 引入了“树形化”的概念:当单个桶中的链表长度超过一个阈值(默认是 8)时,链表将转换为红黑树。红黑树的时间复杂度为 O(log n),大大提升了在大量哈希冲突时的性能。
2. 阈值(Threshold)调整
- JDK 8 对
HashMap
的扩容机制进行了调整。HashMap
的初始容量是 16,每次扩容时,容量会翻倍。当HashMap
中的元素数量超过容量乘以加载因子(默认 0.75)时,HashMap
就会扩容。JDK 8 在扩容时,会更合理地处理链表和树的转换,提高了效率。
3. 红黑树转换回链表
- 如果在扩容或删除操作时,红黑树的节点数量下降到一定的阈值(默认是 6),
HashMap
会将红黑树退化回链表。这样可以减少内存消耗,因为链表在节点较少时更节省空间。
4. 优化哈希算法
- JDK 8 对哈希算法进行了优化,通过减少冲突和提高散列均匀性,使得键的分布更加均匀。这进一步降低了链表或红黑树的长度,提升了
HashMap
的整体性能。
1) 关于jdk8中统计字符出现的个数,比较简便的方式,只在jdk8中可以使用,jdk7就不行!
package leetcode;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* @author zhangyu
* @date 2018/12/11 10:01
**/
public class ListTest {
@Test
public void HashMapTest() {
int[] arr = {1, 2, 3, 1, 1, 2, 4, 6};
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : arr) {
map.put(num, map.getOrDefault(num, 0) + 1);
/*if (!map.containsKey(num)) {
map.put(num, 1);
} else {
map.put(num, map.get(num) + 1);
}*/
}
for (int key : map.keySet()) {
System.out.println(key + "--" + map.get(key));
}
}
}
时间复杂度:O(n)
空间复杂度:O(n)
2) 在jdk8中有第三种方式,利用stream的流:
package com.zhang.computetime;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 统计出现次数
*
* @author: zhangyu
*/
public class DemoStatistic {
@Test
public void testDemoStatistic() {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 2, 3, 1));
Map<Integer, Long> map = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
for (int key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
}
}
时间复杂度:O(n)
空间复杂度:O(n)