I have an object with a list of maps. Each map looks like this:
{ id: "something", link: "someLink" }
I am trying to create an array list of all the id’s in the maps. I can do this with a simple loop
List<String> Ids = new ArrayList<>(); List<Map<String, String>> maps = pojo.getMaps(); for(Map<String, String> map: maps) { Ids.add(map.get("id")); }
But how is this done in one line using java 8 streams? I have never used it with maps so I am lost. I assume it would be along the lines of something like this but i honestly dont know
List<String> ids = pojo.getMaps().stream().map(Map.Entry:: ???? ).collect(Collectors.toList())
Advertisement
Answer
pojo.getMaps().stream()
So far, so good. You now have a stream of Map<String, String>
objects. We need to just get the keys from this. So, given one of your weird map things, how do we turn that into the key value?
Looks like a trivial map.get("id")
does that job, no?
So let’s put that in the lambda:
pojo.getMaps().stream().map(theMap -> theMap.get("id"))
and now we have a Stream<String>
with ids.
HOWEVER, big note!
The fact that you start out with a map object that looks like an object is a giant code smell. Most likely you should go back a few steps in your project and fix that instead. You really ought to have a class that represents this link concept:
@Value public class Link { String id, link; }
and go from there:
listOfLinks.stream().map(Link::getId).distinct().collect(...);
NB: The above uses Lombok’s @Value
.
functional is just a tool
Note that there is no need to rewrite your code to ‘use java 8 features’. Compare:
var ids = pojo.getMaps().stream() .map(m -> m.get("id")) .collect(Collectors.toList());
with:
var ids = new ArrayList<String>(); for (var m : pojo.getMaps()) ids.add(m.get("id"));
it’s about the same amount of code.