Reputation:
I have a map like the following:
class Person {
Long personId;
String name;
/*Getters and Setters*/
}
I have populated a map Map<Long, Person> personMap = new HashMap<>();
The key of the map is the personId itself. I have a list of personIds like so,
List<Long> coolPeople = new ArrayList<>();
now I want to iterate through the map and get all the values with the keys corresponding the ids in the list coolPeople
, and then store it in a List.
How can I achieve this in Java 8 optimally?
Upvotes: 14
Views: 36903
Reputation: 398
I found this question looking for a way to filter the entries in a map using stream()
and after reading the current answers I feel like this one is missing:
Map<String, String> result = myMap.entrySet().stream()
.filter(entry -> { /* apply conditions for entry.getKey() and entry.getValue() here */})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Upvotes: 5
Reputation: 59
If you are interested in returning a map, you could use the following:
public static <K, V> Map<K, V> filterByKeys(final Map<K, V> map, final Iterable<K> keys) {
final Map<K, V> newMap = new HashMap<>();
keys.forEach(key -> Optional.ofNullable(map.get(key))
.ifPresent(value -> newMap.put(key, value)));
return newMap;
}
Upvotes: 1
Reputation: 11201
Correct this :
List<Long> coolPeople = new ArrayList();
and for the other part :
List<Person> coolPersons=new ArrayList<Person>();
for (Long id:coolPeople) {
Person p=map.get(id);
coolPersons.add(p);
}
Feel free to comment if you are having any questions.
Upvotes: -2
Reputation: 394096
It would be more efficient to iterate over the identifiers of the List
and look them up in the Map
, since search by key in a HashMap
takes expected O(1)
time, while the search in the List
can take O(n)
time at the worst case.
List<Person> people =
coolPeople.stream()
.map(id -> personMap.get(id)) // or map(personMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Upvotes: 17
Reputation: 328855
An alternative solution (and possibly more efficient - depending on the size of the map / list) would be to copy the map and act on the keySet
directly:
Map<Long, Person> copy = new HashMap<> (personMap);
copy.keySet().retainAll(coolPeople);
Collection<Person> result = copy.values();
Upvotes: 10