Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collect stream of EntrySet to LinkedHashMap

I want to collect the stream to a LinkedHashMap<String, Object>.

I have a JSON resource that is stored in LinkedHashMap<String, Object> resources. Then I filter out JSON elements by streaming the EntrySet of this map. Currently I am collecting the elements of stream to a regular HashMap. But after this I am adding other elements to the map. I want these elements to be in the inserted order.

final List<String> keys = Arrays.asList("status", "createdDate");

Map<String, Object> result = resources.entrySet()
        .stream()
        .filter(e -> keys.contains(e.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

result.put("date", "someDate");
return result;

That is why I want to collect the stream to a LinkedHashMap<String, Object>. How can I achieve this?

like image 204
xtra Avatar asked Oct 24 '18 17:10

xtra


People also ask

Can we cast HashMap to LinkedHashMap?

Of course, you can create a LinkedHashMap from a HashMap , but it isn't guaranteed that the LinkedHashMap will have the same order that your original did.


2 Answers

You can do this with Stream:

Map<String, Object> result = resources.entrySet()
            .stream()
            .filter(e -> keys.contains(e.getKey()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));

The part (x, y) -> y is because of mergeFunction when find duplicate keys, it returns value of second key which found. the forth part is mapFactory which a supplier providing a new empty Map into which the results will be inserted.

like image 80
Amin Avatar answered Oct 28 '22 12:10

Amin


An alternate way of doing this using Map.forEach is:

Map<String, Object> result = new LinkedHashMap<>();
resources.forEach((key, value) -> {
    if (keys.contains(key)) {
        result.put(key, value);
    }
});
result.put("date", "someDate");

and if you could consider iterating on the keySet as an option:

Map<String, Object> result = new LinkedHashMap<>();
resources.keySet().stream()
        .filter(keys::contains)
        .forEach(key -> result.put(key,resources.get(key)));
result.put("date", "someDate");
like image 28
Naman Avatar answered Oct 28 '22 12:10

Naman