Reputation: 21
I have an array of values
String [] str = { ONE, TWO, THREE };
and some key-value pairs stored in a map
Map<String, String> map;
How can I use the Stream API to get all entries from the map whose key is contained in the array?
Upvotes: 2
Views: 2795
Reputation: 34460
One way is to stream the array and collect the elements into a new map, with the keys being the elements and the values taken from your map for each key:
Map<String, String> result = Arrays.stream(str)
.collect(Collectors.toMap(e -> e, map::get));
This assumes all the elements of the array are keys in the map, and no duplicate elements on the array.
If you want to filter out elements that aren't keys of the map, use filter
on the stream:
Map<String, String> result = Arrays.stream(str)
.filter(map::containsKey)
.collect(Collectors.toMap(e -> e, map::get));
And if you have duplicate elements in the array:
Map<String, String> result = Arrays.stream(str)
.filter(map::containsKey)
.collect(Collectors.toMap(e -> e, map::get, (o, n) -> o));
The last parameter (o, n) -> o
is a merge function that is applied to values when there are duplicates keys on the map. In this case, the merge function keeps the old value and discards the new one.
Upvotes: 1
Reputation: 298143
You didn’t specify the form of the result.
If you want the same map but only containing the specified keys, you can use
Map<String, String> map;
Map<String, String> result = new HashMap<>(map);
result.keySet().retainAll(Arrays.asList(str));
If the old state is not needed anymore and the map is mutable, you may apply the second statement to the map
without creating a copy.
A solution always creating a new Map
would be
Map<String, String> result = Arrays.stream(str)
.collect(HashMap::new, (m, k) -> m.computeIfAbsent(k, map::get), Map::putAll);
If you just want an array containing values corresponding to the array containing the keys, you could use
String[] result = new String[str.length];
Arrays.setAll(result, ix -> map.get(str[ix]));
or
String[] result = Arrays.stream(str).map(map::get).toArray(String[]::new);
Upvotes: 1
Reputation: 269667
If the map and the set of keys to remove are small, start with a copy of the map, and then modify it.
Map<String, String> filtered = new HashMap<>(map);
filtered.keySet().retainAll(Arrays.asList(str));
If the map is so much larger than the set of keys to remove that making a copy is undesirable, you can build a new map with only the correct entries:
Set<String> filter = new HashSet<>(Arrays.asList(str));
Map<String, String> filtered = map.entrySet().stream()
.filter(e -> filter.contains(e.getKey))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Upvotes: 1
Reputation: 615
I assume that when you say you want the entries from this map, you mean the values so here is how I would do it
String[] str = {"ONE", "TWO", "THREE"};
Map<String, String> map = <Your map's here>;
List<String> values = Stream.of(str)
.filter(map::containsKey)
.map(map::get)
.collect(Collectors.toList());
Upvotes: 1