能否借助双向链表特性对LinkedHashMap进行双向迭代?
Absolutely! Since LinkedHashMap maintains a doubly linked list of its entries to preserve either insertion order (default) or access order (if configured with the accessOrder constructor parameter), it fully supports both forward and reverse iteration. Let me break this down with practical examples:
Forward Iteration (Default Behavior)
This is the out-of-the-box experience—LinkedHashMap's default iterators (from entrySet(), keySet(), or values()) traverse the doubly linked list using the next pointer, following the order entries were added (or accessed, if access-order is enabled).
Here's a quick example:
LinkedHashMap<String, Integer> linkedMap = new LinkedHashMap<>(); linkedMap.put("Apple", 1); linkedMap.put("Banana", 2); linkedMap.put("Cherry", 3); // Forward iteration (follows insertion order) System.out.println("Forward Iteration:"); for (Map.Entry<String, Integer> entry : linkedMap.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } // Output: Apple: 1, Banana: 2, Cherry: 3
Reverse Iteration
While LinkedHashMap doesn't include a built-in descendingIterator() method (unlike TreeMap), its underlying doubly linked list structure makes reverse iteration easy to implement with standard Java APIs. Here are two reliable approaches:
1. Convert to a List and Use ListIterator
Since LinkedHashMap's entry set maintains its ordered sequence, we can convert it to an ArrayList and use a ListIterator to traverse from the end to the start:
// Convert entry set to an ordered list List<Map.Entry<String, Integer>> entryList = new ArrayList<>(linkedMap.entrySet()); // Reverse iteration using ListIterator System.out.println("\nReverse Iteration (ListIterator):"); ListIterator<Map.Entry<String, Integer>> listIterator = entryList.listIterator(entryList.size()); while (listIterator.hasPrevious()) { Map.Entry<String, Integer> entry = listIterator.previous(); System.out.println(entry.getKey() + ": " + entry.getValue()); } // Output: Cherry: 3, Banana: 2, Apple: 1
2. Use LinkedList's Built-in Reverse Iterator
We can collect the entry set into a LinkedList (which preserves the original order) and leverage its built-in descendingIterator():
// Collect entries into a LinkedList and use descendingIterator() System.out.println("\nReverse Iteration (LinkedList Descending Iterator):"); LinkedList<Map.Entry<String, Integer>> entryLinkedList = new LinkedList<>(linkedMap.entrySet()); entryLinkedList.descendingIterator() .forEachRemaining(entry -> System.out.println(entry.getKey() + ": " + entry.getValue())); // Output: Cherry: 3, Banana: 2, Apple: 1
A Quick Note on Internal Access
If you're working with a custom subclass of LinkedHashMap, you might be tempted to access the internal doubly linked list nodes (via fields like before/after in Java 8+). This is not recommended—it breaks encapsulation and may fail across different Java versions. Stick to the standard API methods above for portability and maintainability.
内容的提问来源于stack exchange,提问作者Nishit Dhruv

