Reputation: 1358
I got the follwoing question:
I have a Map<?,?>
and I parse it from an PList file, simplified like:
Map<String, String> m = (Map<String, String>) getMap();
The getMap()
method just reads the file (.plist).
I want to parse all the values to String, but unfortunately the Map contains Integers, causing an error later in the process.
So I wanted to write a method using the filter to convert everything to String:
My approach is:
m.entrySet().stream()
.map(e -> e.getValue())
.filter(e -> e instanceof Integer)
.map(e -> String.valueOf(e))
.collect(Collectors.toMap(e -> e.keys(), e -> e.getValue()));
The problem is, that the collect at the end is not working, how can I fix this? The result should be a map again.
Thank you a lot!
Upvotes: 5
Views: 8062
Reputation: 6037
You're misunderstanding how Collectors.toMap
works - it takes two functions, one that given an entry produces a new key, and one that given an entry produce a new value. Each entry in the map then has both of these functions applied to it and the resulting key/value for that single element are used to construct the new entry in the new map.
Also, by mapping each entry to just the value, you lose the association between keys and values, which means you can't reconstruct the map correctly.
A corrected version would be:
Map<String, String> n;
n = m.entrySet()
.stream()
.filter(e -> e.getValue() instanceof Integer)
.collect(Collectors.toMap(e -> e.getKey(),
e -> String.valueOf(e.getValue())));
See fgb@'s answer below for a more concise version using replaceAll
.
Upvotes: 11
Reputation: 18569
The replaceAll
method is probably more suitable for this. It can be used like:
m.replaceAll((k, v) -> String.valueOf(v));
Upvotes: 2
Reputation: 109557
Map<String, String> m2 = m.entrySet().stream()
.collect(Collectors.toMap(e -> Objects.toString(e.getKey()),
e -> Objects.toString(e.getValue())));
This will turn both key and value into strings by toString. A null (value) will be turned into "null".
Upvotes: 1
Reputation: 34460
You have a few errors in your code.
First, as you are mapping each entry to its value, you are losing the keys.
Then, when you filter, you are keeping only Integer
values in the stream, which will yield an incomplete map.
Finally, in Collectors.toMap
you are using e.keys()
and e.getValue
, which are incorrect, because e.keys()
is not a method of neither Map.Entry
nor String
, and because you'd need to use e.getValue()
instead of e.getValue
.
The code should be as follows:
m.entrySet().stream().collect(Collectors.toMap(
e -> e.getKey(),
e -> e.getValue() instanceof Integer ?
String.valueOf(e.getValue()) :
e.getValue()));
Upvotes: 2