194

I know LinkedHashMap has a predictable iteration order (insertion order). Does the Set returned by LinkedHashMap.keySet() and the Collection returned by LinkedHashMap.values() also maintain this order?

Machavity
  • 30,841
  • 27
  • 92
  • 100
user256239
  • 17,717
  • 26
  • 77
  • 89
  • 1
    Since all the answers address the issue of `values()` as well as `keySet()`, I've expanded the question to include that. This means more questions can be closed as duplicates of this. – Duncan Jones Oct 22 '14 at 08:27

5 Answers5

270

The Map interface provides three collection views, which allow a map's contents to be viewed as a set of keys, collection of values, or set of key-value mappings. The order of a map is defined as the order in which the iterators on the map's collection views return their elements. Some map implementations, like the TreeMap class, make specific guarantees as to their order; others, like the HashMap class, do not.

-- Map

This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).

-- LinkedHashMap

So, yes, keySet(), values(), and entrySet() (the three collection views mentioned) return values in the order the internal linked list uses. And yes, the JavaDoc for Map and LinkedHashMap guarantee it.

That is the point of this class, after all.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • 10
    the iteration over the map is also done faster using a LinkedHashMap than a HashMap. – Thierry May 27 '10 at 19:26
  • @Thierry: Yeah, I should have mentioned that. Whoops. – Powerlord May 28 '10 at 19:08
  • 3
    values() returns a collection. not a List. how does it keep it in order? – Dejell Dec 15 '14 at 12:01
  • 8
    @Dejel `Collection` is just the base class for what values() returns. The implementation of the Collection it returns is still controlled by the `LinkedHashMap`. In `LinkedHashMap`'s case, it's returning a [`LinkedValues`](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/LinkedHashMap.java#l584) instance, a private class inside LinkedHashMap.java. – Powerlord Dec 15 '14 at 15:12
  • 4
    A LinkedHashMap's keyset in my case is NOT in the order represented in the map. Very puzzled by this. – Alkanshel Jan 09 '16 at 04:08
  • 3
    Thank you for linking to documentation (from `Map`) that explicitly ties the order of a map to the iterators on the map's collection views (and making clear what those collection views are). That was the missing piece for me. – LarsH Jun 02 '16 at 20:46
  • @Amalgovinus: this is weird, according to the source code, it returns a `LinkedEntrySet` (though the javadoc only specifies it returns a `Set`, and `Set`s are not supposed to have iteration order guarantee, so the doc could be clearer). See http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/LinkedHashMap.java#LinkedHashMap.entrySet%28%29 – FBB Mar 06 '17 at 20:40
  • @FBB `Set` doesn't have an order guarantee, but implementations can if they so choose. `LinkedHashMap.Entry` is an internal class used for entries in a `LinkedHashMap`. As you might expect from it being a doubly linked list, each one stores a reference to the previous and next items. `LinkedIterator` explicitly uses the next entry during iteration and each of the 3 `Set`s iterators inherit from that. – Powerlord Mar 07 '17 at 02:16
  • @Powerlord: I think you replied to the version of my comment before I edited it. – FBB Mar 07 '17 at 15:41
  • @Powerlord Although _"the JavaDoc for Map and LinkedHashMap guarantee it"_ I think it wouldn't hurt to reinforce it in `LinkedHashMap` javadoc. I think the reason people come to this post is because it's not that easy to figure the answer. – Gustavo Feb 10 '23 at 15:18
12

Looking at the source, it looks like it does. keySet(), values(), and entrySet() all use the same entry iterator internally.

sblundy
  • 60,628
  • 22
  • 121
  • 123
8

Don't get confused with LinkedHashMap.keySet() and LinkedHashMap.entrySet() returning Set and hence it should not guarantee ordering !

Set is an interface with HashSet,TreeSet etc beings its implementations. The HashSet implementation of Set interface does not guarantees ordering. But TreeSet does. Also LinkedHashSet does.

Therefore it depends on how Set has been implemented in LinkedHashMap to know whether the returning Set reference will guarantee ordering or not. I went through the source code of LinkedHashMap, it looks like this:

private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}

Thus LinkedHashMap/HashMap has its own implementation of Set i.e. KeySet. Thus don't confuse this with HashSet.

Also, the order is maintained by how the elements are inserted into the bucket. Look at the addEntry(..) method of LinkedHashMap and compare it with that of HashMap which highlights the main difference between HashMap and LinkedHashMap.

as.tek
  • 937
  • 3
  • 14
  • 20
  • 6
    While this answer definitely presents useful information, it doesn't really answer the question. It is basically saying they CAN have predictable iteration order. – Tuupertunut Dec 29 '16 at 04:04
5

You can assume so. The Javadoc says 'predictable iteration order', and the only iterators available in a Map are those for the keySet(), entrySet(), and values().

So in the absence of any further qualification it is clearly intended to apply to all of those iterators.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

AFAIK it is not documented so you cannot "formally" assume so. It is unlikely, however, that the current implementation would change.

If you want to ensure order, you may want to iterate over the map entires and insert them into a sorted set with an order function of your choice, though you will be paying a performance cost, naturally.

Uri
  • 88,451
  • 51
  • 221
  • 321
  • Do you mean entrySet() guarantees the order, by keySet() doesn't? – user256239 May 27 '10 at 18:53
  • 1
    @kknight: I'm not sure. the javadoc states: "This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).". However, the JavaDocs for the JDK are very ambiguous in general. – Uri May 27 '10 at 19:08
  • 5
    If even entrySet() doesn't guarantee the iteration order, then what is the difference between LinkedHashMap and HashMap? How can we take advantage of the predictable iteration order in a LinkedHashMap instance? – user256239 May 27 '10 at 19:10
  • 2
    It most certainly *is* documented. Answer is completely incorrect. – user207421 Oct 05 '16 at 22:42