Java LinkedHashSet使用双向链表,它也可以向后迭代吗?

qnakjoqk  于 2023-05-05  发布在  Java
关注(0)|答案(3)|浏览(203)

Oracle-Documentation对LinkedHashSet有如下说明:“Set接口的哈希表和链表实现,具有可预测的迭代顺序。这种实现与HashSet的不同之处在于,它维护了一个贯穿其所有条目的双向链表。
你可以得到的迭代器是按插入顺序的。反向插入顺序的迭代在技术上也是可行的,因为它是一个链接的。
可以创建这样的反向迭代器吗(或者甚至可以创建一个既做反向迭代器又做ListIterator)?

xzv2uavs

xzv2uavs1#

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());
}
cqoc49vn

cqoc49vn2#

LinkedHashMap迭代器只支持向前。你可以在github镜像中的OpenJDK中阅读它的实现。它不像是私下实现ListIterator并秘密支持向后迭代的实现。
哈希表查找为您提供了一个指向列表中某个条目的指针。要删除它,您需要对上一个列表条目的引用。这就是为什么LinkedHashMap需要使用双向链表的原因。

tpxzln5u

tpxzln5u3#

JEP 431: Sequenced Collections在即将到来的Java版本21中添加了一个reversed()方法到LinkedHashSet。可以以标准的方式迭代集合的这种反转视图。

myLinkedHashSet.reversed().forEach(element -> {
  // Do something with the element
});

为了回答这个特定的问题,可以从这个反向视图中检索迭代器,就像任何集合一样。

Iterator<Object> iterator = myLinkedHashSet.reversed().iterator();

相关问题