Map 双列集合,是键值对形式存在的。
HashMap: 哈希表
LinkedHashMap:哈希表+双向链表
TreeMap: 红黑树
HashTable: 哈希表
注意细节:
hashMap 可以null键 null值
hashTable 不可以null键null值
- HashMap: JDK1.8 之前 HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间
- LinkedHashMap: LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。详细可以查看:《LinkedHashMap 源码详细分析(JDK1.8)》
- Hashtable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的.(修改数据时锁整个表(方法加synchronize,table数组使用transient修饰 private transient Entry<?,?>[] table)。大部分方法(涉及线程安全问题的方法)都是同步的。所以线程安全)
- TreeMap: 红黑树(自平衡的排序二叉树)

哈希表
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
数组的特点是:寻址容易,插入和删除困难;
而链表的特点是:寻址困难,插入和删除容易。
那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法,我们可以理解为“链表的数组”,如图:

存储和去重复过程在HashSet中解释过。Set集合看:Set集合
2.Map集合 双列集合 —》方法
(1) put 添加
(2) get(key)获取
(3)遍历:
① entrySet---->Map.Entry
entrySet是获取到一个Set集合,其中放的是Map.Entry,而Map.Entry里是已键值对形式存在的。
HashMap<Integer, Student> studentsMap = new HashMap<>();
Set<Entry<Integer,Student>> set2 = studentsMap.entrySet();
//foreach遍历
for (Entry<Integer, Student> e : set2) {
System.out.println(e.getKey()+"::"+e.getValue());
}
//Iterator遍历
Iterator<Entry<Integer, Student>> it = set2.iterator();
while (it.hasNext()) {
System.out.println(it.next().getValue());
}
② keySet
keySet是获取到一个Set集合,里边存放的是所有的key,然后根据get(key k)的方法,获取值
Set<Integer> keySet = studentsMap.keySet();
for (Integer i : keySet) {
System.out.println(studentsMap.get(i));
}
map实现统计字符串出现的次数
思路,key是字符,value是个数,将字符串转成数组,遍历,如果containsKey() 就把value加1再put进去,如果不包含直接保存,字符的value=1
public static void main(String[] args) {
// 统计一个字符串中每个字符出现的次数
String s = "adadsafqkjhdkjhkasasd";
//创建HashMap集合来存储字符和次数
Map<Character, Integer> map = new HashMap<>();
// 将字符串转化成字符数组
char[] charArr = s.toCharArray();
// 遍历字符数组统计字符个数
for(char ch : charArr) {
if (map.containsKey(ch)) {
// 如果hashMap集合中包含这个字符,则在原来的次数上加1
map.put(ch, map.get(ch)+1);
}else {
// 如果hashMap集合中不包含这个字符,则给这个字符一个初始次数
map.put(ch, 1);
}
}
System.out.print(map);
}
本文深入解析Java中的Map集合,包括HashMap、LinkedHashMap、TreeMap和HashTable的内部结构、特点及应用场景。探讨了HashMap在JDK1.8前后的变化,以及LinkedHashMap如何保持键值对的插入顺序。
406

被折叠的 条评论
为什么被折叠?



