最简单的数据结构是数组和对象(指针)
一切复杂的数据结构都可以基于数组和对象实现
HashMap
HashMap的底层实现:
数组+单向链表/红黑树
底层结构
每一个桶都可以装一个单链表
什么是哈希码和哈希函数?
哈希函数:就是一个方法
同一个字符串使用同样的哈希函数(散列函数)计算出来的哈希码必定是一样的
不同的字符串使用同样的哈希函数计算出来的哈希码大概率是不一样的,小概率是一样的
什么是哈希碰撞/哈希冲突?
如果有两个字符串通过同样的哈希算法计算出来的哈希码是一样的,则称他们发生了哈希碰撞、哈希冲突。
如何保证集合中元素的唯一性?
1.遍历+比较 性能是硬伤
2.通过hash运算,给字符串生成指纹
如何解决哈希冲突?
1.开放地址法
2.拉链法(链地址法) HashMap默认使用拉链法。 未发生冲突则存入桶中,纵向扩展,发生了哈希冲突则存在桶后面的单链表中,横向扩展。
当某一个链表的长度超过阈值8的时候,此时链表会转为红黑树结构
HashSet类
需要一个元素唯一的集合
存储键值对的话用HashSet
只存储单个元素的话用HashMap
无序,唯一
HashSet的底层是HashMap
存储在HashMap中的元素,实际上是存储在一个HashMap中的key位置
遍历HashMap和HashSet的几种方式
不可以用普通for循环,非线性结构不支持用索引号遍历
1. 增强型for循环
2.迭代器
1)先获取Entry集合,然后再获取Entry集合的迭代器
2)先获取key的集合,然后再获取key集合的迭代器
HashMap的put方法的源码解读
需要存一对一的结构时候,例如:学号-姓名 用HashMap存储
一对多 用ArrayList 、Linkedlist
HashMap存储学生信息遍历展示
import java.util.HashMap;
public class Test {
static HashMap<String,HashMap<String,HashMap<String,Integer>>> map = new HashMap<>();
static {
//50班第一组信息
HashMap<String,Integer> stu_50_1 = new HashMap<>();
stu_50_1.put("50_1_1",77);
stu_50_1.put("50_1_2",90);
stu_50_1.put("50_1_3",88);
//50班第二组信息
HashMap<String,Integer> stu_50_2 = new HashMap<>();
stu_50_2.put("50_2_1",90);
stu_50_2.put("50_2_2",70);
stu_50_2.put("50_2_3",60);
//50班第一组
HashMap<String,HashMap<String,Integer>> map50 = new HashMap<>();
map50.put("第一组",stu_50_1);
//50班第二组
map50.put("第二组",stu_50_2);
//50班
map.put("通达50班",map50);
//51班第一组信息
HashMap<String,Integer> stu_51_1 = new HashMap<>();
stu_51_1.put("50_1_1",7);
stu_51_1.put("50_1_2",9);
stu_51_1.put("50_1_3",8);
//51班第二组信息
HashMap<String,Integer> stu_51_2 = new HashMap<>();
stu_51_2.put("50_2_1",9);
stu_51_2.put("50_2_2",7);
stu_51_2.put("50_2_3",6);
//51班第一组
HashMap<String,HashMap<String,Integer>> map51 = new HashMap<>();
map51.put("第一组",stu_51_1);
//51班第二组
map51.put("第二组",stu_51_2);
//51班
map.put("通达51班",map51);
}
public static void main(String[] args) {
map.forEach((className,cMap) -> {
System.out.println(className + "信息展示:");
System.out.println("***********************");
cMap.forEach((groupName,stu) -> {
System.out.println(groupName);
stu.forEach((stuName,score) -> {
System.out.println("姓名:" + stuName + " " + "分数:" + score);
System.out.println("*********************");
});
});
});
}
}
测试结果:
归纳总结