An API I am using has a method that returns a Map<String, Object>
, but I know the Object
's are String
's in this case, so I want it as a Map<String, String>
.
But for some reason I can't just cast it, Java says Map<String, Object>
cannot be casted to Map<String, String>
, for some reason.
I used:
Map<String, Object> tempMap = someApiMethodReturningAMap();
Map<String, String> map = new HashMap<String, String>();
for (String i : tempMap.keySet()) {
map.put(i, String.valueOf(tempMap.get(i)));
}
as a workaround, but is there an easier way?
We can convert a map to a string in java using two array lists. In this, we first fill the map with the keys. Then, we will use keySet() method for returning the keys in the map, and values() method for returning the value present in the map to the ArrayList constructor parameter.
To convert an object to a Map , call the Object. entries() method to get an array of key-value pairs and pass the result to the Map() constructor, e.g. const map = new Map(Object. entries(obj)) .
Convert Object to String in java using toString() method of Object class or String. valueOf(object) method. Since there are mainly two types of class in java, i.e. user-defined class and predefined class such as StringBuilder or StringBuffer of whose objects can be converted into the string.
1. Overview. Map is one of the most common data structures in Java, and String is one of the most common types for a map's key.
Well you can't safely cast it to a Map<String, String>
because even though you know you've only got strings as the values, the compiler doesn't. That's like expecting:
Object x = "foo";
String y = x;
to work - it doesn't; you need to explicitly cast.
Likewise you can explicitly cast here, too, if you go via Object
:
Map<String, Object> x = ...;
Map<String, String> y = (Map<String, String>) (Object) x;
Now you'll get a warning saying that it's an unchecked cast, because unlike the earlier "object to string" cast, there's no execution-time check that it's really valid. Type erasure means that a map doesn't really know its key/value types. So you end up with checking only being done when elements are fetched:
import java.util.*;
class Test {
public static void main(String[] args) {
Map<String, Object> x = new HashMap<>();
x.put("foo", "bar");
x.put("number", 0);
Map<String, String> y = (Map<String, String>) (Object) x;
// This is fine
System.out.println(y.get("foo"));
// This goes bang! It's trying to cast an Integer to a String
System.out.println(y.get("number"));
}
}
So if you really want to avoid creating a new map, this "cast via Object
" will work - but it's far from ideal.
Your approach is safer, although you can make it slightly more efficient by avoiding the lookup:
public static Map<String, String> copyToStringValueMap(
Map<String, Object> input) {
Map<String, String> ret = new HashMap<>();
for (Map.Entry<String, Object> entry : input.entrySet()) {
ret.put(entry.getKey(), (String) entry.getValue());
}
return ret;
}
A Java 8 solution:
private Map<String, String> stringifyValues(Map<String, Object> variables) {
return variables.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String) e.getValue()));
}
Good solutions here, but I want to add another one that taking into consideration handling null
values:
Map<String,Object> map = new HashMap<>();
Map<String,String> stringifiedMap = map.entrySet().stream()
.filter(m -> m.getKey() != null && m.getValue() !=null)
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With