Oracle-Documentation对LinkedHashSet有如下说明:“Set接口的哈希表和链表实现,具有可预测的迭代顺序。这种实现与HashSet的不同之处在于,它维护了一个贯穿其所有条目的双向链表。你可以得到的迭代器是按插入顺序的。反向插入顺序的迭代在技术上也是可行的,因为它是一个双链接的。可以创建这样的反向迭代器吗(或者甚至可以创建一个既做反向迭代器又做ListIterator)?
xzv2uavs1#
LinkedHashSet没有公开任何API来向后迭代它。虽然这会对性能产生非常糟糕的影响,但您可以将LinkedHashSet复制到List(保留其顺序),然后对其进行反向迭代:
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()); }
cqoc49vn2#
LinkedHashMap迭代器只支持向前。你可以在github镜像中的OpenJDK中阅读它的实现。它不像是私下实现ListIterator并秘密支持向后迭代的实现。哈希表查找为您提供了一个指向列表中某个条目的指针。要删除它,您需要对上一个列表条目的引用。这就是为什么LinkedHashMap需要使用双向链表的原因。
ListIterator
tpxzln5u3#
JEP 431: Sequenced Collections在即将到来的Java版本21中添加了一个reversed()方法到LinkedHashSet。可以以标准的方式迭代集合的这种反转视图。
reversed()
myLinkedHashSet.reversed().forEach(element -> { // Do something with the element });
为了回答这个特定的问题,可以从这个反向视图中检索迭代器,就像任何集合一样。
Iterator<Object> iterator = myLinkedHashSet.reversed().iterator();
3条答案
按热度按时间xzv2uavs1#
LinkedHashSet
没有公开任何API来向后迭代它。虽然这会对性能产生非常糟糕的影响,但您可以将LinkedHashSet
复制到List
(保留其顺序),然后对其进行反向迭代:cqoc49vn2#
LinkedHashMap迭代器只支持向前。你可以在github镜像中的OpenJDK中阅读它的实现。它不像是私下实现
ListIterator
并秘密支持向后迭代的实现。哈希表查找为您提供了一个指向列表中某个条目的指针。要删除它,您需要对上一个列表条目的引用。这就是为什么LinkedHashMap需要使用双向链表的原因。
tpxzln5u3#
JEP 431: Sequenced Collections在即将到来的Java版本21中添加了一个
reversed()
方法到LinkedHashSet
。可以以标准的方式迭代集合的这种反转视图。为了回答这个特定的问题,可以从这个反向视图中检索迭代器,就像任何集合一样。