HashMap深度解析:JDK1.7与JDK1.8的区别与优化

需积分: 9 0 下载量 118 浏览量 更新于2024-08-28 收藏 4KB MD 举报
"深入解剖HashMap,探讨其内部机制和优化策略" HashMap是Java编程语言中一个重要的数据结构,主要用于存储键值对。它基于哈希表实现,提供了快速的查找、插入和删除操作,平均时间复杂度为O(1)。在JDK 1.7及之前的版本中,HashMap主要由数组和链表组成;自JDK 1.8开始,为了进一步优化性能,引入了红黑树的数据结构。 在JDK 1.7中,HashMap的数组长度总是2的幂次方。这是因为HashMap使用key的哈希码与数组长度减一进行按位与运算(&)来确定元素在数组中的位置,确保结果落在0到数组长度减1的范围内。为了保证这种均匀分布,数组长度选择2的幂次方可以避免按位与运算的某些位始终为0,从而提高散列效果。此外,HashMap在计算索引时,会先进行一次右移操作,然后再进行按位与,以减少哈希冲突的可能性,提升性能。 在链表实现上,JDK 1.7使用了头插法。这意味着新插入的entry会位于链表头部,这样在查找时可以通过索引快速获取链表头,避免遍历整个链表。但这也导致了插入操作需要移动已存在的entry,以保持索引对应关系。当两个key相同时,put方法会覆盖旧值并返回旧值,否则返回null。 对于哈希冲突的处理,HashMap依赖于equals()和hashCode()方法。如果两个对象相等(根据equals()),那么它们的hashCode()必须相等。反之,如果hashCode()不等,则对象不等。但是,hashCode()相等并不意味着对象一定相等,还需要通过equals()来判断。这遵循了Java中的哈希约定。 在JDK 1.7中,当HashMap容量达到一定阈值(默认为0.75 * 当前容量)时,会触发扩容操作。扩容会创建一个新的两倍大小的数组,并将原数组中的所有元素重新哈希到新数组中。扩容策略有助于在一定程度上平衡链表长度,减少因哈希冲突产生的长链表,提高查找效率。 JDK 1.8引入了红黑树,当链表长度超过一定阈值(8)时,链表会转换为红黑树。红黑树是一种自平衡二叉查找树,其查找、插入和删除操作的时间复杂度都接近O(log n),优于链表的O(n)。这一改变进一步提升了HashMap在高冲突情况下的性能。 HashMap的设计与优化是围绕着提高查找效率、降低哈希冲突和平衡数据分布展开的。通过对哈希函数的精心设计、扩容策略的调整以及链表和红黑树的智能切换,HashMap能够在各种场景下提供高效的服务。理解这些内部机制对于编写高效的Java代码至关重要。

@Service("AdminService") public class AdminServiceImpl implements AdminService { @Autowired private AdminDao adminDao; @Autowired private DocDao docDao; @Autowired private LogDao logDao; @Autowired private UserDao userDao; @Autowired private RoleDao roleDao; @Override public Admin login(String username, String password) { try { return adminDao.login(username, md5(password)); }catch (Exception e) { e.printStackTrace(); return null; } } @Override public Map<String, Integer> index() { Map<String,Integer> map = new HashMap<>(); Long templateNum = docDao.count(null); map.put("templateNum",templateNum.intValue()); List<Log> logs = logDao.selectAll(); int nowlogNum = 0; Date now = new Date(); for (Log log : logs) { Date date = log.getTime(); if(DateUtils.isSameDay(now, date)){ nowlogNum++; } } map.put("nowlogNum",nowlogNum); Long logNum= logDao.count(); map.put("logNum",logNum.intValue()); Long userNum = userDao.count(null); map.put("userNum",userNum.intValue()); Long roleNum = roleDao.count(); map.put("roleNum",roleNum.intValue()); return map; } public static String md5(String password) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(password.getBytes(StandardCharsets.UTF_8)); StringBuilder hexString = new StringBuilder(); for (byte b : hash) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } }通俗的详细的讲一下这段代码

2023-05-22 上传
2023-05-17 上传