Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting raw Map to Map<Object, Object>, will there be any issue?

Tags:

java

I need to convert raw Map to Map<string,string>, and I think I have to first convert the raw map to Map<Object,Object> and then convert it again to Map<String,String>.

code snippet goes like below.

    Map obj1 = new HashMap();
    obj1.put("key1", 1);
    obj1.put("key2", false);
    obj1.put("key3", 3.94f);


    Map<Object, Object> obj2 = obj1;

    Map<String, String> obj = new HashMap<String,String>();

    for (Map.Entry<Object, Object> entry: obj2.entrySet()) {
        obj.put(entry.getKey().toString(), entry.getValue().toString());
    }

I guess it would work in any condition but I want to hear from others about possible danger of this code.(any possiblities for ClassCastException for example?)

Please also let me know if you have a better idea.

-- revised code

    Map obj1 = new HashMap();
    obj1.put(2, 1);
    obj1.put(true, false);
    obj1.put(4.4f, 3.94f);

    Map<String, String> obj = new HashMap<String,String>();
    for (Object k : obj1.keySet()){
        obj.put(k.toString(), obj1.get(k).toString());
    }

Since raw Map entries will contain key/value of Objects anyway, I think I don't need temporary Map<Object,Object>. Just iterating over each item works well and I don't see any issues so far.

like image 416
Adrian Seungjin Lee Avatar asked Mar 16 '16 04:03

Adrian Seungjin Lee


2 Answers

If You Look out the Definition of HashMap in jdk 1.4 It was earlier Implements using Object Class when generics Concept not came.

When generics is Introduced this object is Replaced with <T>. But If you Still don't use Generics Type Safe then Internally this Statement new HashMap() reflects a instance of <Object, Object>. Better To use directly a a new HashMap() is better idea. There should no need of Map <Object, Object> obj2.

So, GO For this.. a better approach.

Map obj1 = new HashMap();
  obj1.put("key1", 1);
  obj1.put("key2", false);
  obj1.put("key3", 3.94f);


Map<Object, Object> obj2 = obj1;

Map<String, String> obj = new HashMap<String,String>();

for (Object obj_Entry : obj1.entrySet()) {
    Map.Entry entry = (Map.Entry) obj_Entry; // This will Work Fine all Time. 
    obj.put(entry.getKey().toString(), entry.getValue().toString());

}
like image 56
Vikrant Kashyap Avatar answered Nov 01 '22 00:11

Vikrant Kashyap


Your code will not generate ClassCastExceptions. Actually you are not doing any casting here. You just call the toString() method of every key/value pair to make it a string. As long as toString() returns a valid value of your objects. Your code will be fine.

But your code may produce NullPointerExceptions if your obj1 contain null keys or objects

obj1.put(null, "null value")

Also note that some key collisions may occur if toString() methods return same String value for two keys. This is unlikely but it is possible.

like image 33
dishan Avatar answered Nov 01 '22 00:11

dishan