ZZZ
ZZZ

Reputation: 3764

Get a subset of LinkedHashMap and preserve the order

Unlike HashMap, order matters in LinkedHashMap. And the order here is insertion order.

Let say I have a LinkedHashMap like the following (ordered from the top to bottom, left part is key, right part is value):

1:"One"
2:"Two"
3:"Three"
4:"Four"

Then I have a list of keys, which contains, let's say, (3,1).

What I want to do is to loop through the LinkedHashMap in order and pick out the entries whose key is in the list.

So the result I want to have is (1 is still before 3 because that's the order before filtering):

1:"One"
3:"Three"

Here is my code:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SelectCertainEntriesFromLinkedHashMap {
    public static void main(String args[]) {
        Map<Integer,String> linkedHashMap = new LinkedHashMap<Integer,String>();
        linkedHashMap.put(1, "One");
        linkedHashMap.put(2, "Twe");
        linkedHashMap.put(3, "Three");
        linkedHashMap.put(4, "Four");
        
        List<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(1);
        
        Map<Integer,String> selectedlinkedHashMap = new LinkedHashMap<Integer,String>();
        
        //will this iterator iterate the keys in the order of the map (1, 2, 3, 4)? Or just random order?
        Iterator<Integer> itr = linkedHashMap.keySet().iterator();
        while(itr.hasNext()) {
            Integer key = itr.next();
            if (list.contains(key)) {
                selectedlinkedHashMap.put(key, linkedHashMap.get(key));
                System.out.println(key + ":" + linkedHashMap.get(key));
            }
        }
    
}

The above code return the result I like. But I am not sure if it is guaranteed.

1:"One"
3:"Three"

The question is:

Iterator<Integer> itr = linkedHashMap.keySet().iterator();

The above line will get a iterator from a set and Set is not ordered. So will this cause the keys in random order? if yes, I can't keep the original order (not guaranteed) of my map after filtering…

Could anybody help me with this?

Upvotes: 4

Views: 2915

Answers (4)

M. Justin
M. Justin

Reputation: 21162

The Java 21 documentation for keySet method in LinkedHashMap class is more explicit about the ordering than in prior versions of Java:

The encounter order of the keys in the view matches the encounter order of mappings of this map.

So as of Java 21, the answer is clearly documented that yes, linkedHashMap.keySet().iterator() will return keys in the same order as the map elements.

Prior versions of Java did have the same behavior, but the documentation around it was less explicit.

Therefore, regardless of the version of Java, the keySet iteration order can be depended upon to return elements in the same order as the LinkedHashMap entries.

Upvotes: 1

Girish Rao
Girish Rao

Reputation: 2669

The iterator returned from keySet().iterator() should return an ordered Set. Documentation from the Map API:

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.

So in the LinkedHashMap case I interpret this as saying the iterator will return an ordered Set. It's true the LinkedHashMap API is not explicit about this but you could just try it out and observe your output.

Upvotes: 5

Ed Morales
Ed Morales

Reputation: 1037

have you tried it? I'm not sure it returns them in the same order as they were inserted, but in this particular case, you could create a TreeSet with the KeySet obtained and since they are integers its gonna be naturally order. 1 and then 3.

kinda like:

Set<Integer> set = new TreeSet<Integer>(linkedHashMap.keySet());

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500855

When you call keySet(), that creates a view of the keys based on the underlying data. Admittedly it's not very clearly documented, but as it is just a view, it would be incredibly weird for that view to be iterated in a different order.

You could check the implementation of course, but I'm sure it's fine.

Upvotes: 5

Related Questions