PageSourceSearch

https://blog.xiongtianci.com/atips/assets/js/v-49cda92a.6c28bae4.js

js xiongtianci.com collected 2026-10-10 02:43:31 UTC 18,453 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkatips=self.webpackChunkatips||[]).push([[4594],{9667:(n,s,a)=>{a.r(s),a.d(s,{data:()=>e});const e={key:"v-49cda92a",path:"/java/container/collection/java-collection-set.html",title:"Collection - Set",lang:"zh-CN",frontmatter:{},excerpt:"",headers:[{level:2,title:"Set 简介",slug:"set-简介",children:[]},{level:2,title:"HashSet",slug:"hashset",children:[]},{level:2,title:"LinkedHashSet",slug:"linkedhashset",children:[]},{level:2,title:"参考资料",slug:"参考资料",children:[]}],filePathRelative:"java/container/collection/java-collection-set.md",git:{updatedTime:1719836412e3,contributors:[{name:"Tianci.Xiong",email:"[email protected]",commits:3},{name:"TianCi.Xiong",email:"[email protected]",commits:2}]}}},1895:(n,s,a)=>{a.r(s),a.d(s,{default:()=>t});const e=(0,a(6252).uE)('<h1 id="collection-set" tabindex="-1"><a class="header-anchor" href="#collection-set" aria-hidden="true">#</a> Collection - Set</h1><h2 id="set-简介" tabindex="-1"><a class="header-anchor" href="#set-简介" aria-hidden="true">#</a> Set 简介</h2><p><em>Set</em> 注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,<strong>不允许有重复的元素</strong>。对象的相等性本质是对象的 <strong>hashCode</strong> 值(Java 是依据对象的内存地址计算出的此序号)判断的,如果想要让两个不同的对象视为相等的,就必须覆盖 <em>Object</em> 的 <code>hashCode()</code> 方法和 <code>equals()</code> 方法。</p><p><img src="//gcore.jsdelivr.net/gh/tiancixiong/atips@img-230529/images/java/container/collection/image-20211023214554753.png" alt="image-20211023214554753"></p><ul><li><em><strong>Set</strong></em> 继承了 Collection 的接口。实际上,Set 就是一个 Collection,只是行为不同(这是继承和多态思想的典型应用,表现不同的行为);</li><li><em><strong>SortedSet</strong></em> 继承了 <em>Set</em> 的接口。<em>SortedSet</em> 中的内容是排序的唯一值,排序的方法是通过比较器(Comparator);</li><li><em><strong>NavigableSet</strong></em> 继承了 SortedSet 的接口。它提供了丰富的查找方法:如&quot;获取大于/等于某值的元素&quot;、“获取小于/等于某值的元素”等等;</li><li><em><strong>AbstractSet</strong></em> 是一个抽象类,它继承于 AbstractCollection,AbstractCollection 实现了 <em>Set</em> 中的绝大部分方法,为实现 <em>Set</em> 的实例类提供了便利;</li><li><em><strong>HashSet</strong></em> 类依赖于 HashMap,它实际上是通过 <em>HashMap</em> 实现的。<em>HashSet</em> 使用散列函数存储元素,元素是无序的、散列的;</li><li><em><strong>TreeSet</strong></em> 类依赖于 TreeMap,它实际上是通过 TreeMap 实现的。TreeSet 将元素存储在红-黑树数据结构中,元素是有序的,它是按自然排序或者用户指定比较器排序的 <em>Set</em>;</li><li><em><strong>LinkedHashSet</strong></em> 是按插入顺序排序的 Set;</li><li><em><strong>EnumSet</strong></em> 是只能存放 Emum 枚举类型的 Set。</li></ul><hr><p><img src="img/20200221190717.png" alt="img"></p><h2 id="hashset" tabindex="-1"><a class="header-anchor" href="#hashset" aria-hidden="true">#</a> HashSet</h2><p><em>HashSet</em> 是对 <em>HashMap</em> 的简单包装,对 <em>HashSet</em> 的函数调用都会转换成合适的 <em>HashMap</em> 方法。</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">;</span>\n\n<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HashSet</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span>\n    <span class="token keyword">extends</span> <span class="token class-name">AbstractSet</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span>\n    <span class="token keyword">implements</span> <span class="token class-name">Set</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">,</span> <span class="token class-name">Cloneable</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span>Serializable</span>\n<span class="token punctuation">{</span>\n\t<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n\t<span class="token keyword">private</span> <span class="token keyword">transient</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> map<span class="token punctuation">;</span> <span class="token comment">//HashSet里面有一个HashMap</span>\n    <span class="token comment">// PRESENT 是用于关联 map 中当前操作元素的一个虚拟值</span>\n    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">Object</span> PRESENT <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    \n    <span class="token keyword">public</span> <span class="token class-name">HashSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    \n    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token class-name">E</span>
1 e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//转换成 map 方法</span>\n        <span class="token keyword">return</span> map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>e<span class="token punctuation">,</span> PRESENT<span class="token punctuation">)</span><span class="token operator">==</span><span class="token keyword">null</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n<span class="token punctuation">}</span>\n</code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><ul><li>HashSet 中维护了一个 HashMap 对象 <code>map</code>,HashSet 的重要方法,如 <code>add()</code>、<code>remove()</code>、<code>iterator()</code>、<code>clear()</code>、<code>size()</code> 等都是围绕 map 实现的。</li><li>HashSet 类中通过定义 <code>writeObject()</code> 和 <code>readObject()</code> 方法确定了其序列化和反序列化的机制。</li><li><code>PRESENT</code> 是用于关联 map 中当前操作元素的一个虚拟值。</li></ul><p>哈希表边存放的是哈希值。HashSet 存储元素的顺序并不是按照存入时的顺序(和 List 显然不同) 而是按照<strong>哈希值</strong>来存的,所以取数据也是按照哈希值取的。元素的哈希值是通过元素的 <code>hashCode()</code> 方法来获取的,HashSet 首先判断两个元素的哈希值,如果哈希值一样,接着会比较 <code>equals()</code> 方法。如果 <code>equls()</code> 结果为 true ,HashSet 就视为同一个元素;如果 <code>equals()</code> 为 false 就不是同一个元素。</p><p>哈希值相同 <code>equals()</code> 为 false 的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存在一列中。</p><blockquote><p>HashSet 通过 hashCode 值来确定元素在内存中的位置。一个 hashCode 位置上可以存放多个元素。</p></blockquote><h2 id="linkedhashset" tabindex="-1"><a class="header-anchor" href="#linkedhashset" aria-hidden="true">#</a> LinkedHashSet</h2><p><em>LinkedHashSet</em> 是按插入顺序排序的 <em>Set</em>。</p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token keyword">package</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">;</span>\n<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LinkedHashSet</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span>\n    <span class="token keyword">extends</span> <span class="token class-name">HashSet</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span>\n    <span class="token keyword">implements</span> <span class="token class-name">Set</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">E</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">,</span> <span class="token class-name">Cloneable</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span>Serializable</span> <span class="token punctuation">{</span>\n    \n    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n    <span class="token keyword">public</span> <span class="token class-name">LinkedHashSet</span><span class="token punctuation">(</span><span class="token keyword">int</span> initialCapacity<span class="token punctuation">,</span> <span class="token keyword">float</span> loadFactor<span class="token punctuation">)</span> <span class="token punctuation">{</span>
1\n        <span class="token keyword">super</span><span class="token punctuation">(</span>initialCapacity<span class="token punctuation">,</span> loadFactor<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    \n    <span class="token keyword">public</span> <span class="token class-name">LinkedHashSet</span><span class="token punctuation">(</span><span class="token keyword">int</span> initialCapacity<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        <span class="token keyword">super</span><span class="token punctuation">(</span>initialCapacity<span class="token punctuation">,</span> <span class="token number">.75f</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    \n    <span class="token keyword">public</span> <span class="token class-name">LinkedHashSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">,</span> <span class="token number">.75f</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>\n<span class="token punctuation">}</span>\n</code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><p><code>LinkedHashSet</code> 内的个构造方法都是调用父类 <code>HashSet</code> 的构造方法。需要强调的是:<strong>LinkedHashSet 构造方法实际上调用的是父类 HashSet 的非 public 构造方法。</strong></p><div class="language-java ext-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">// java.util.HashSet</span>\n<span class="token class-name">HashSet</span><span class="token punctuation">(</span><span class="token keyword">int</span> initialCapacity<span class="token punctuation">,</span> <span class="token keyword">float</span> loadFactor<span class="token punctuation">,</span> <span class="token keyword">boolean</span> dummy<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LinkedHashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>initialCapacity<span class="token punctuation">,</span> loadFactor<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">public</span> <span class="token class-name">HashSet</span><span class="token punctuation">(</span><span class="token keyword">int</span> initialCapacity<span class="token punctuation">,</span> <span class="token keyword">float</span> loadFactor<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n    map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>initialCapacity<span class="token punctuation">,</span> loadFactor<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n</code></pre><div class="line-numbers"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>不同于 <code>HashSet</code> 内 <code>public</code> 构造方法中初始化的 <code>HashMap</code> 实例,这个构造方法中,初始化了 <code>LinkedHashMap</code> 实例。</p><p>也就是说,实际上,<code>LinkedHashSet</code> 维护了一个双链表。由双链表的特性可以知道,它是按照元素的插入顺序保存的。所以,这就是 <code>LinkedHashSet</code> 中存储的元素是按照插入顺序保存的原理。</p><h2 id="参考资料" tabindex="-1"><a class="header-anchor" href="#参考资料" aria-hidden="true">
1#</a> 参考资料</h2><ul><li>https://dunwu.github.io/javacore/container/java-container-set.html</li></ul>',23),p={},t=(0,a(3744).Z)(p,[["render",function(n,s){return e}]])},3744:(n,s)=>{s.Z=(n,s)=>{for(const[a,e]of s)n[a]=e;return n}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.