Demo05.java 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package course;
  2. /**
  3. * @author WanJl
  4. * @version 1.0
  5. * @title Demo05
  6. * @description HashMap
  7. * @create 2026/7/31
  8. */
  9. public class Demo05 {
  10. /*
  11. HashMap集合
  12. HashMap集合是实现了Map接口的一种基于【哈希表结构】实现的集合。
  13. HashMap集合依赖 hashCode方法和equals方法来保证 键Key的唯一。
  14. 所以如果自定义类型想要存入到HashMap的Key中,就一定要重写【hashCode方法和equals方法】
  15. 哈希值 :
  16. 哈希值是JDK根据对象的地址,或者字符串或者数字算出来的int类型的数值。
  17. 获取哈希值的方式就是Object类中的hashCode(),返回的就是哈希码值
  18. 哈希值的特点:
  19. 同一个对象多次调用hashCode()方法,返回的哈希值是相同的。
  20. 默认情况下,不同的对象的哈希值是不同的,重写hashCode()可以让我们实现不同对象的哈希值相同。
  21. 一般是在多个个对象的所有属性值完全相同时,hashCode()方法需要返回相同的哈希值。
  22. 哈希表结构是什么?
  23. 哈希表本质来讲,就可以理解为 数组+链表
  24. 上面是数组,每个元素都有对应的索引值
  25. 其实是一个默认长度为16的数组。
  26. 我们往里面添加的键值对的时候,会计算键的哈希值。计算的哈希值其实就是int整数
  27. 所以可能出现这样情况:
  28. 张三 --hash运算(hashCode) --> 15
  29. 李四 --hash运算(hashCode) --> 87
  30. 王五 --hash运算(hashCode) --> 66
  31. 赵六 --hash运算(hashCode) --> 20
  32. wanjl --hash运算(hashCode) --> 15
  33. 哈么么 --hash运算(hashCode) --> 70
  34. HashMap--JDK1.7及之前
  35. 数组+链表 的哈希表结构
  36. 1、创建一个默认长度为16的,默认的负载因子0.75的数组,数组名table
  37. 2、根据元素的哈希值跟数组长度进行计算,计算出应该存入的位置。
  38. 3、判断当前的位置是否为null,如果是null就直接存入
  39. 4、如果位置不是null,表示有元素,那么就调用equals方法比较这两个元素的属性值,判断是不是同一个。
  40. 5、如果判断发现两个对象是同一个,就不存了。如果不是同一个则存入数组,老的元素挂在新元素的下边。
  41. 能让两个相同哈希值的对象以链表的方式挂到后面。
  42. 原因就只有一个:
  43. 虽然哈希值相同,但是equals比较不同。
  44. 风险和弊端:
  45. 如果出现越来越多的哈希值相同,但是equals比较为false,的元素。
  46. 就会导致链表过长,性能下降。
  47. HashMap--JDK1.8之后
  48. JAVA1.8之后,引入了 红黑树,1.8之后的HashMap有两种形态:
  49. 第1种:数组+链表--哈希表
  50. 第2种:是在哈希表满足了某些条件后,从数组+链表 转换为 数组+红黑树。保证性能不会降低。
  51. 简单来说,就是链表的节点数超过8个,就转为红黑树。
  52. HashMap的数组默认长度是16
  53. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
  54. 默认的负载因子是0.75,当已经存入数组的元素超过长度的0.75,那么就对数组进行扩容
  55. static final float DEFAULT_LOAD_FACTOR = 0.75f;
  56. HashMap从数组+链表的结构转为数组+红黑树的结构的阈值,树化阈值是8,链表节点长度超过8就树化。
  57. static final int TREEIFY_THRESHOLD = 8;
  58. 当节点长度小于6的时候,会从红黑树退化会链表
  59. static final int UNTREEIFY_THRESHOLD = 6;
  60. 数组+链表转为红黑树的第2个条件:数组长度大于64
  61. static final int MIN_TREEIFY_CAPACITY = 64;
  62. 总结:
  63. 1、HashMap的结构是 数组+链表
  64. 2、达到一定条件,会转为 数组+红黑树
  65. 3、树化条件:数组长度大于64,链表节点长度超过8。
  66. 4、链表节点长度小于6就退化回链表。
  67. */
  68. }