擅长:python、mysql、java
<p>Java中的一个简单方法是创建一个实现<code>Set</code>和<code>List</code>接口的包装器类,该类同时包含<code>HashSet</code>和{<cd4>}。更新操作将需要同时更新两个内部集合,而读取操作将映射到任何一个提供正确语义和最佳性能的内部集合。唯一稍微有点棘手的方法是<code>iterator()</code>,您需要安排<code>remove</code>更新两个集合。在</p>
<p>这种方法将为读取操作提供“两全其美”的性能,但更新速度必然较慢。特别是,在给定位置插入和删除将是<code>O(N)</code>操作。在</p>
<p>(我注意到LinkedHashSet不是一个直接的解决方案,因为它不提供<code>get(int)</code>方法。您可以通过LinkedHashSet迭代器来实现这个方法,使其成为<code>O(N)</code>操作。可能不是你想要的。)</p>
<p><strong跟进</p>
<p>我找不到同时实现<code>Set</code>和<code>List</code>接口的通用实现类。我认为原因是当你把接口组合起来时,会出现语义异常。例如,(如@ColinD注释)如果使用列表中已有的元素调用<code>E set(int, E)</code>,则不清楚结果应该是什么。以一种让所有人都满意的方式来处理这件事可能是不可能的,我能理解为什么他们会决定不去柏油池游泳。在</p>
<p>但是,如果您要为应用程序的内部使用创建<code>Set</code>+<code>List</code>类,我不认为这是一个大问题。你也是</p>
<ul>
<li>为适合您的应用程序选择语义</li>
<li>编写应用程序,使其完全不使用该方法,或者</li>
<li>编写应用程序的代码,以避免被异常情况影响。在</li>
</ul>
<p>(例如,您可以将其编码为忽略<code>set</code>方法的结果,如果存在重复,则抛出未经检查的异常;如果存在重复,则返回<code>null</code>或某个可分辨对象。)</p>
<p>就记录而言,自定义集合类违反接口约定并不是不可原谅的。事实上,即使是Java设计人员也会这样做——请参见IdentityHashMap。不可原谅的是没有在javadocs中记录违反合同的行为。在</p>