<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>代码原理 on 洛克里亚的五度 博客</title>
    <link>https://lv-blog.pages.dev/tags/%E4%BB%A3%E7%A0%81%E5%8E%9F%E7%90%86/</link>
    <description>Recent content in 代码原理 on 洛克里亚的五度 博客</description>
    <generator>Hugo</generator>
    <language>zh</language>
    <lastBuildDate>Wed, 08 Jul 2026 17:38:40 +0800</lastBuildDate>
    <atom:link href="https://lv-blog.pages.dev/tags/%E4%BB%A3%E7%A0%81%E5%8E%9F%E7%90%86/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>H mod C = H &amp; (C - 1) ?</title>
      <link>https://lv-blog.pages.dev/posts/programming/why-why-why/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%A6%82%E4%BD%95%E6%B1%82%E6%A8%A1/</link>
      <pubDate>Wed, 08 Jul 2026 17:38:40 +0800</pubDate>
      <guid>https://lv-blog.pages.dev/posts/programming/why-why-why/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%A6%82%E4%BD%95%E6%B1%82%E6%A8%A1/</guid>
      <description>&lt;p&gt;在 Java 后端开发面试或源码阅读中，&lt;code&gt;HashMap&lt;/code&gt; 永远是避不开的核心。很多人能熟练地背出它的扩容阈值、红黑树化条件，但当深入到源码底层，看到诸如 &lt;code&gt;e.hash &amp;amp; (newCap - 1)&lt;/code&gt; 和 &lt;code&gt;e.hash &amp;amp; oldCap&lt;/code&gt; 这样的位运算时，往往会陷入沉思。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一-起源为什么数组长度必须是-2-的次幂&#34;&gt;一、 起源：为什么数组长度必须是 2 的次幂？&lt;/h2&gt;
&lt;p&gt;在散列表中，为了让数据均匀分布，最直观的想法是对哈希值进行&lt;strong&gt;取模（求余数）&lt;/strong&gt;：&lt;/p&gt;
$$\text{索引位置} = \text{hash} \pmod{\text{Capacity}}$$&lt;p&gt;然而，在 CPU 的底层底层执行中，&lt;strong&gt;除法和取模（%）是非常昂贵的算术操作&lt;/strong&gt;（可能需要几十个时钟周期）。为了追求极致的性能，底层的数论定理为我们提供了一个完美的替代方案：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;数学定理&lt;/strong&gt;：当容量 $C$ 是 $2$ 的次幂（$2^n$）时，对于任意整数 $H$，满足：&lt;/p&gt;
$$H \pmod C \equiv H \ \&amp; \ (C - 1)$$&lt;/blockquote&gt;
&lt;p&gt;位运算（&lt;code&gt;&amp;amp;&lt;/code&gt;）在 CPU 中只需要 &lt;strong&gt;1 个时钟周期&lt;/strong&gt;！为了享受到这个性能红利，HashMap 在源码中将容量死死限制为 2 的次幂：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 默认初始容量 16 (2的4次方)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; DEFAULT_INITIAL_CAPACITY &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 1 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; 4;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;裁剪器的魔术hash--newcap---1&#34;&gt;裁剪器的魔术：&lt;code&gt;hash &amp;amp; (newCap - 1)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;以容量 &lt;code&gt;16&lt;/code&gt; 为例，&lt;code&gt;16 - 1 = 15&lt;/code&gt;（二进制：&lt;code&gt;0000 1111&lt;/code&gt;）。任何 Hash 值与 &lt;code&gt;15&lt;/code&gt; 进行 &lt;code&gt;&amp;amp;&lt;/code&gt; 运算，高位都会被无情“抹零”，只有最后 4 位被保留下来：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
