0

When i cast Collections.synchronizedMap( ) to hash map it returns class cast exception but when i cast Map to hash map it works fine.

As per my understanding Collections.synchronizedMap( ) also returns map .

Then Why i am getting this exception .

How to over come it.

Example code

 public class Main_1 {
  public static void main(String[] args) throws UnknownHostException, IOException {
    Map m = new HashMap();
    m.put("sachin", "sacjdeva");
     // Throws exception here 
    HashMap hm = (HashMap) Collections.synchronizedMap(m);
    //No exception
    HashMap hm = (HashMap)(m)
    System.out.println(hm);
   }
 }

Ok if its synchronizedMap and throws class cast exception can i convert this SynchronizedMap to HashMap.

T-Bag
  • 10,916
  • 3
  • 54
  • 118
  • `Map` is an interface but `HashMap` is implementation type. So better to cast it to `Map` – SacJn Oct 20 '15 at 06:28
  • You cannot cast an Interface to an implementing-interface class, you can invoke the hashmap constructor giving that map as input, instead. – morels Oct 20 '15 at 07:18
  • Possible duplicate of [Difference between Dynamic and Static type assignments in Java](http://stackoverflow.com/questions/20504714/difference-between-dynamic-and-static-type-assignments-in-java) – Erwin Bolwidt Oct 20 '15 at 07:32

6 Answers6

2

Collections.synchronizedMap(m) doesn't return a HashMap, so you can't cast it to HashMap. It returns a SynchronizedMap instance.

You can assign it to a Map :

Map smap = Collections.synchronizedMap(m);

In your "normal Map" example :

HashMap hm = (HashMap)(m);

is not a "normal Map". There is no such thing as "normal Map".

You assign a HashMap instance to it here :

Map m = new HashMap();

which is the only reason you can later cast it to HashMap.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • I know i does not return hash map it returns only map . – T-Bag Oct 20 '15 at 06:44
  • @ShowStopper I'm not just referring to the return type of that method, which is `Map`, I'm referring to the actual `Map` implementation that this method returns, which is `SynchronizedMap`, and therefore can't be cast to `HashMap`. – Eran Oct 20 '15 at 06:45
1

It returns an instance of Map, i.e. an instance of a class (that you don't need to know) that implements the Map interface. You don't need to cast it to HashMap, which is another class implementing the same Map interface.

HashMap hm = (HashMap)(m)

works only because the actual concrete class of m is HashMap. It wouldn't work if you initialized m with

Map m = new TreeMap();

for example.

You should program to interfaces rather than programming to concrete types. Your variable should be of type Map. You should also avoid using raw types, and specify the generic parameters of the map:

Map<String, String> map = new HashMap<>();
m.put("sachin", "sacjdeva");
Map<String, String> synchronizedMap = Collections.synchronizedMap(m);
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

Map is interface. HashMap is one implementation, SynchronizedMap is another implementation.

SynchronizedMap is not a HashMap, so you cannot cast it to it.

HashMap is a HashMap, so you can cast it.

In your example it is better to cast to Map if you need, as it would allow you to work with any implementation.

BobTheBuilder
  • 18,858
  • 6
  • 40
  • 61
  • SynchronizedMap is not an implementation, but a method. Pls see [http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map)](http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map)) – morels Oct 20 '15 at 07:19
  • 1
    It is an implementation. Take a look at the method's implementation - it returns a `SynchronizedMap` class – BobTheBuilder Oct 20 '15 at 07:47
0

Hashmap is not synchronized so it can't be cast to Synchronized Map while Map is an interface so what ever type of synchronized Map returned it implements Map so can be caseted to Map

karim mohsen
  • 2,164
  • 1
  • 15
  • 19
0

SynchronizedMap returns a different implementation than HashMap implementation, so you can't cast it to HashMap.

But you can do this:

Map<String, String> m = new HashMap<String, String>();
m.put("sachin", "sacjdeva");

Map<String, String> hm = Collections.synchronizedMap(m);
Salah
  • 8,567
  • 3
  • 26
  • 43
0

Collections.synchronizedMap(Map) returns an instance of SynchronizedMap which is an inner class of Collections class. Following piece of code will get the actual class name being returned.

System.out.println(Collections.synchronizedMap(m).getClass().getName());

SynchronizedMap implements the Map interface but it is not a subclass of HashMap. So casting SynchronizedMap to HashMap will cause ClassCastException.

Developer
  • 534
  • 1
  • 11
  • 21