8

I'm trying to understand if I can get a linked list of entries from my linked hash map. I can get entrySet() and then using iterator I get through each entry in the insertion order. This will give me the linked list of entries in the insertion order.

Can I guarantee the same result if I use the values() method?

9
  • 1
    Your question title doesn't really match question which you are asking at the end. Can you edit your title to actually be related to answers which you expect to get? Commented Apr 10, 2019 at 12:03
  • 4
    keySet(), values() and entrySet() will all three give you internally backed views without additional cost. All of them are just views to the actual internal representation, they all represent the same. In particular, no copies or anything are created, it comes with no real cost. This is documented in Javadoc, please check the documentation first. Commented Apr 10, 2019 at 12:04
  • 1
    "Get LinkedList of entries .. with values() method" can't be done since values() doesn't return entries (as key-value pairs, but only list of values). Your question looks more like "Does LinkedHashMap guarantee same order for entrySet() and values()?" (but I am not sure if that is what you really wanted to ask because I still don't know what is the purpose of LinkedList here) Commented Apr 10, 2019 at 12:11
  • 2
    If that is not enough, then it is debatable and, if absolute necessary, should technically not be relied on. However, even if the Java-devs don't see this as documented promised feature, I highly doubt they would ever change that, as it would break an extreme amount of code. Commented Apr 10, 2019 at 12:17
  • 2
    The Iteration order also depends on the constructor you use. Because you could specify if you need accessed order (like an LRU cache) or insertion order. Commented Apr 10, 2019 at 12:32

3 Answers 3

6

As of Java 8, let's take a look at the source of LinkedHashMap. We can deduct the internal behavior from the entrySet() and values() method definitions:

  • The method entrySet() returns new LinkedEntrySet() on the line 627 which uses new LinkedEntryIterator() as the iterator as of line 634.
  • The method values() returns new LinkedValues() on the line 581 which uses new LinkedValueIterator() as the iterator as of line 588.

Now, let's look at the sources of those inner classes defined in the very same file beginning from line 737:

final class LinkedValueIterator extends LinkedHashIterator implements Iterator<V> { public final V next() { return nextNode().value; } } final class LinkedEntryIterator extends LinkedHashIterator implements Iterator<Map.Entry<K,V>> { public final Map.Entry<K,V> next() { return nextNode(); } } 

They both extend LinkedHashIterator which implies the accessing of values of the map would be treated the same way using both entrySet() and values().

Sign up to request clarification or add additional context in comments.

3 Comments

It's nice to be able to poke around in the source code. I fully agree with your answer. Nevertheless, I think such things must be mentioned (clearly stated) in the docs, so you don't have to figure it out on your own.
@AndrewTobilko: Cannot agree more. The first I looked to was the Java 8 documentation, however, I haven't found anything useful to mention in here. Looking to the source code shall be the last choice after seeing official tutorials, wiki, documentation and unit tests.
The main point is: This could change in Java 9, 10 or 11, as long it is not part of the contract (API docs). However, this is purely hypothetical, of course: It will not change. As long as relying on the iteration order is not relevant for, say, the implementation of an emergency shutdown of a nuclear power plant, one shouldn't worry about that.
1

Can I guarantee the same result if I use the values() method?

Basically, LinkedHashMap#values returns you a restricted view of the internal structure. And I'd venture to say it must give the same result. It's not explicitly stated in the docs

Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

but the highlighted excerpt makes me think so.

"The same result" is more than a data collection: it includes the way the data should be iterated (the iterator). "changes to the map are reflected in the set" to me implies that both iterators share one algorithm, which, on the same piece of data, would result in the same behaviour.

Comments

0

I think so. Internally the class uses java.util.LinkedHashMap.LinkedHashIterator, which is used by both entrySet() and values(), so if the former allows you to iterate in the insertion order, the latter will do the same.

2 Comments

I also "think so" (and basically "know" it, also by looking at the code). But looked up the JavaDocs and didn't see an explicit guarantee. What comes closest to a guarantee is the statement ""The spliterators returned by ... the collections returned by .... collection view methods ... report Spliterator.ORDERED" ...
I agree totally.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.