Convert HashMap.toString() back to HashMap in Java
I put a key-value pair in a Java HashMap开发者_C百科
and converted it to a String
using the toString()
method.
Is it possible to convert this String
representation back to a HashMap
object and retrieve the value with its corresponding key?
Thanks
It will work if toString() contains all data needed to restore the object. For example it will work for map of strings (where string is used as key and value):
// create map
Map<String, String> map = new HashMap<String, String>();
// populate the map
// create string representation
String str = map.toString();
// use properties to restore the map
Properties props = new Properties();
props.load(new StringReader(str.substring(1, str.length() - 1).replace(", ", "\n")));
Map<String, String> map2 = new HashMap<String, String>();
for (Map.Entry<Object, Object> e : props.entrySet()) {
map2.put((String)e.getKey(), (String)e.getValue());
}
This works although I really do not understand why do you need this.
toString()
approach relies on implementation of toString()
and it can be lossy in most of the cases.
There cannot be non lossy solution here. but a better one would be to use Object serialization
serialize Object to String
private static String serialize(Serializable o) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
deserialize String back to Object
private static Object deserialize(String s) throws IOException,
ClassNotFoundException {
byte[] data = Base64.getDecoder().decode(s);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data));
Object o = ois.readObject();
ois.close();
return o;
}
Here if the user object has fields which are transient, they will be lost in the process.
old answer
Once you convert HashMap to String using toString(); It's not that you can convert back it to Hashmap from that String, Its just its String representation.
You can either pass the reference to HashMap to method or you can serialize it
Here is the description for toString() toString()
Here is the sample code with explanation for Serialization.
and to pass hashMap to method as arg.
public void sayHello(Map m){
}
//calling block
Map hm = new HashMap();
sayHello(hm);
you cannot do this directly but i did this in a crazy way as below...
The basic idea is that, 1st you need to convert HashMap String into Json then you can deserialize Json using Gson/Genson etc into HashMap again.
@SuppressWarnings("unchecked")
private HashMap<String, Object> toHashMap(String s) {
HashMap<String, Object> map = null;
try {
map = new Genson().deserialize(toJson(s), HashMap.class);
} catch (TransformationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
private String toJson(String s) {
s = s.substring(0, s.length()).replace("{", "{\"");
s = s.substring(0, s.length()).replace("}", "\"}");
s = s.substring(0, s.length()).replace(", ", "\", \"");
s = s.substring(0, s.length()).replace("=", "\":\"");
s = s.substring(0, s.length()).replace("\"[", "[");
s = s.substring(0, s.length()).replace("]\"", "]");
s = s.substring(0, s.length()).replace("}\", \"{", "}, {");
return s;
}
implementation...
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Name", "Suleman");
map.put("Country", "Pakistan");
String s = map.toString();
HashMap<String, Object> newMap = toHashMap(s);
System.out.println(newMap);
i converted HashMap into an String using toString() method and pass to the another method that take an String and convert this String into HashMap object
This is a very, very bad way to pass around a HashMap.
It can theoretically work, but there's just way too much that can go wrong (and it will perform very badly). Obviously, in your case something does go wrong. We can't say what without seeing your code.
But a much better solution would be to change that "another method" so that it just takes a HashMap
as parameter rather than a String representation of one.
You can make use of Google's "GSON" open-source Java library for this,
Example input (Map.toString) : {name=Bane, id=20}
To Insert again in to HashMap you can use below code:
yourMap = new Gson().fromJson(yourString, HashMap.class);
That's it Enjoy.
(In Jackson Library mapper It will produce exception "expecting double-quote to start field name")
What did you try?
objectOutputStream.writeObject(hashMap);
should work just fine, providing that all the objects in the hashMap implement Serializable.
You cannot revert back from string to an Object. So you will need to do this:
HashMap<K, V> map = new HashMap<K, V>();
//Write:
OutputStream os = new FileOutputStream(fileName.ser);
ObjectOutput oo = new ObjectOutputStream(os);
oo.writeObject(map);
oo.close();
//Read:
InputStream is = new FileInputStream(fileName.ser);
ObjectInput oi = new ObjectInputStream(is);
HashMap<K, V> newMap = oi.readObject();
oi.close();
Are you restricted to use only HashMap
??
Why can't it be so much flexible JSONObject
you can do a lot with it.
You can convert String jsonString
to JSONObject jsonObj
JSONObject jsonObj = new JSONObject(jsonString);
Iterator it = jsonObj.keys();
while(it.hasNext())
{
String key = it.next().toString();
String value = jsonObj.get(key).toString();
}
Using ByteStream can convert the String but it can encounter OutOfMemory exception in case of large Strings. Baeldung provides some nice solutions in his pot here : https://www.baeldung.com/java-map-to-string-conversion
Using StringBuilder :
public String convertWithIteration(Map<Integer, ?> map) {
StringBuilder mapAsString = new StringBuilder("{");
for (Integer key : map.keySet()) {
mapAsString.append(key + "=" + map.get(key) + ", ");
}
mapAsString.delete(mapAsString.length()-2, mapAsString.length()).append("}");
return mapAsString.toString(); }
Please note that lambdas are only available at language level 8 and above Using Stream :
public String convertWithStream(Map<Integer, ?> map) {
String mapAsString = map.keySet().stream()
.map(key -> key + "=" + map.get(key))
.collect(Collectors.joining(", ", "{", "}"));
return mapAsString; }
Converting String Back to Map using Stream :
public Map<String, String> convertWithStream(String mapAsString) {
Map<String, String> map = Arrays.stream(mapAsString.split(","))
.map(entry -> entry.split("="))
.collect(Collectors.toMap(entry -> entry[0], entry -> entry[1]));
return map; }
I hope you actually need to get the value from string by passing the hashmap key. If that is the case, then we don't have to convert it back to Hashmap. Use following method and you will be able to get the value as if it was retrieved from Hashmap itself.
String string = hash.toString();
String result = getValueFromStringOfHashMap(string, "my_key");
/**
* To get a value from string of hashmap by passing key that existed in Hashmap before converting to String.
* Sample string: {fld_category=Principal category, test=test 1, fld_categoryID=1}
*
* @param string
* @param key
* @return value
*/
public static String getValueFromStringOfHashMap(String string, String key) {
int start_index = string.indexOf(key) + key.length() + 1;
int end_index = string.indexOf(",", start_index);
if (end_index == -1) { // because last key value pair doesn't have trailing comma (,)
end_index = string.indexOf("}");
}
String value = string.substring(start_index, end_index);
return value;
}
Does the job for me.
It is possible to rebuild a collection out of its string presentation but it will not work if the elements of the collection don't override their own toString
method.
Therefore it's much safer and easier to use third party library like XStream which streams objects in human readable XML.
This may be inefficient and indirect. But
String mapString = "someMap.toString()";
new HashMap<>(net.sf.json.JSONObject.fromObject(mapString));
should work !!!
精彩评论