Now that we have Java 8/streams, we can add one more possible answer to the list:
Assuming that each of the values actually are String objects, the cast to String should be safe. Otherwise some other mechanism for mapping the Objects to Strings may be used.
Map<String,Object> map = new HashMap<>();
Map<String,String> newMap = map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
Answer from skeryl on Stack OverflowNow that we have Java 8/streams, we can add one more possible answer to the list:
Assuming that each of the values actually are String objects, the cast to String should be safe. Otherwise some other mechanism for mapping the Objects to Strings may be used.
Map<String,Object> map = new HashMap<>();
Map<String,String> newMap = map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
If your Objects are containing of Strings only, then you can do it like this:
Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if(entry.getValue() instanceof String){
newMap.put(entry.getKey(), (String) entry.getValue());
}
}
If every Objects are not String then you can replace (String) entry.getValue() into entry.getValue().toString().
apex - How to convert Map<String,Object> into Map<string,string>()? - Salesforce Stack Exchange
java - Converting Map<String,String> to Map<String,Object> - Stack Overflow
Mapping a Bean to Map<String,Object>
dictionary - How to convert Map<Object, Object> to Map<String, String> in java? - Stack Overflow
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()));
}
So you can try like this
map<string,string> newMap= new Map<string,string>();
for(String strKey: mapValues.keyset())
{
newMap.put(strKey, String.valueof(mapValues.get(strKey)));
}
I have tried this worked for me:
enter code here
map<string,object> mspstrToObj = new Map<string,object>();
mspstrToObj.put('key1', 'obj1');
map<string,string> mspstrTostr = new Map<string,string>();
mspstrTostr.put('strKey1',string.valueof(mspstrToObj.get('key1')));
system.debug('=======mspstrTostr====='+mspstrTostr);
You need to create new Map and put the values as per above.
Instead of writing your own loop that calls put, you can putAll, which does the same thing:
filterMapObj.putAll(filterMap);
(See the Javadoc.)
And as Asanka Siriwardena points out in his/her answer, if your plan is to populate filterMapObj immediately after creating it, then you can use the constructor that does that automatically:
filterMapObj = new HashMap<>(filterMap);
But to be clear, the above are more-or-less equivalent to iterating over the map's elements: it will make your code cleaner, but if your reason for not wanting to iterate over the elements is actually a performance concern (e.g., if your map is enormous), then it's not likely to help you. Another possibility is to write:
filterMapObj = Collections.<String, Object>unmodifiableMap(filterMap);
which creates an unmodifiable "view" of filterMap. That's more restrictive, of course, in that it won't let you modify filterMapObj and filterMap independently. (filterMapObj can't be modified, and any modifications to filterMap will affect filterMapObj as well.)
You can simply write
Map<String, Object> filterMapObj = new HashMap<>(filterMap);
The cleanest way to add the properties to the map would be (following on from your example):
for (String propName : properties.stringPropertyNames()) {
map.put(propName, properties.getProperty(propName));
}
This works nicely in this particular case, because the Properties object is really a map containing String keys and values, as the getProperty method makes clear. It's only declared as Map<Object, Object> for horrible backwards-compatibility reasons.
By using the Properties-specific methods, rather than treating this as just a Map<Object, Object>, you can populate your Map<String, String> with perfect type-safety (rather than having to cast).
You can directly convert:
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>((Map)properties);
Hi, the task is to assign every most populated city of each continent to its continent.
"countries" is the map type <String, Country> where String is the country code, and value is just the Country object assigned to that code.
same with "cities", but it's map type <Integer, City> where Integer is ID of the assigned city
The implementation I've made almost provides the solution but it's a map of <String, Optional<City>> instead of <String, City> (where String is the continent, and City is the most populated city)
How to convert the map values of type <Optional<City>> to type <City>?
Map<String, Optional<City>> ex = cities.values().stream()
.collect(Collectors.
groupingBy(p -> countries.get(p.getCountryCode()).getContinent(),
Collectors.maxBy(Comparator.comparing(City::getPopulation))));Also the github with exercises and provided data: https://github.com/deepcloudlabs/stream-api-exercises-part1
City class: https://github.com/deepcloudlabs/stream-api-exercises-part1/blob/master/src/com/example/domain/City.java
Country class: https://github.com/deepcloudlabs/stream-api-exercises-part1/blob/master/src/com/example/domain/Country.java
How about PropertyUtils.describe(object) though it works only for Java Beans (meaning Java Objects that implement getters)
I am assuming that you want to convert "Object[][] obj" to Map. In that case here is my solution:
public static Map<String, String> convert2DArrayObjectToMap(Object[][] object)
{
Map<String, String> map = new TreeMap<>();
if (object != null)
{
for (int i = 0; i < object.length; i++)
{
if (object[i] != null)
{
for (int j = 0; j < object[i].length; j++)
{
map.putAll((TreeMap<String, String>) object[i][j]);
}
}
}
}
return map;
}