【问题标题】:The Java LinkedHashSet uses a doubly-linked list. Can it also be iterated backwards?Java LinkedHashSet 使用双向链表。也可以反向迭代吗?
【发布时间】:2020-07-13 16:29:01
【问题描述】:

Oracle 文档对 LinkedHashSet 进行了如下说明:“Set 接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与 HashSet 的不同之处在于它维护一个贯穿其所有条目的双向链表。”

您可以获得的迭代器是按插入顺序排列的。反向插入顺序的迭代在技术上也是可行的,因为它是双重链接的。

可以创建这样的反向迭代器(甚至可以创建两者的 ListIterator)吗?

【问题讨论】:

  • 没有。只是一个常规的向前迭代器。

标签: java collections linked-list iteration hashset


【解决方案1】:

LinkedHashSet 不公开任何 API 来向后迭代它。尽管这会对性能产生非常糟糕的影响,但您可以将 LinkedHashSet 复制到 List(保留其顺序),然​​后对其进行反向迭代:

LinkedHashSet<SomeClass> myLinkedHashSet = ...;
List<SomeClass> myList = new ArrayList<>(myLinkedHashSet); // Order is retained
ListIterator<SomeClass> myIter = myList.listIterator(myList.size());
while (myIter.hasPrevious()) {
    System.out.println(myIter.previous());
}

【讨论】:

  • 是的,我绝对不会那样做。但是:为什么它是双重联系的呢?因为否则在删除元素时无法修复linkedList?
【解决方案2】:

LinkedHashMap 迭代器只支持前进。你可以在OpenJDK in the github mirror 中阅读它的实现。不像是私下实现ListIterator,暗中支持向后迭代的实现。

哈希表查找为您提供了指向列表中某处的条目的指针。要删除它,您需要对上一个列表条目的引用。这就是 LinkedHashMap 需要使用双向链表的原因。

【讨论】:

  • 感谢第二段,这澄清了我对最佳答案的评论。
猜你喜欢
  • 2016-01-22
  • 2012-05-31
  • 2015-07-14
  • 2015-07-13
  • 2013-10-10
  • 2011-01-03
  • 2020-10-28
相关资源
最近更新 更多