Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Map and ConcurrentHashMap throw a java.lang.UnsupportedOperationException

With this simple code

import scala.collection.JavaConversions._
new java.util.concurrent.ConcurrentHashMap[String,String]  ().toMap.put("abc","def")

Scala throw a java.lang.UnsupportedOperationException.

Why ?

like image 352
Philippe Prados Avatar asked Jul 25 '16 13:07

Philippe Prados


1 Answers

Well this is what happens (I think):

  1. You create a concurrent java hash map with new java.util.concurrent.ConcurrentHashMap[String,String]()
  2. Then you convert it to an immutable scala Map with toMap
  3. As toMapis not defined on java.util.concurrent.ConcurrentHashMap an implicit conversion to a mutable scala map is applied. And toMap then makes of this mutable Map an immutable Map.
  4. Then you call 'put(...)' which is not defined on scala.collection.immutable.Map.
  5. The scala compiler however, conveniently, finds a conversion from scala.collection.immutable.Map to java.util.Map in your import import scala.collection.JavaConversions._ which has a put(...) method defined. However, the conversion returns a wrapper extending AbstractMap.
  6. But there is no put(...) method implemented in that wrapper. Therefore, the call ends up in the default implementation of java.util.AbstractMap which does not really implement put(...) but instead throws an UnsupportedOperationException

I guess the confusion caused by this, is one reason most scala developers prefer import scala.collection.JavaConverters._ over import scala.collection.JavaConversions._ nowadays.

So, I think, this might be what you want to do:

import scala.collection.JavaConverters._
new java.util.concurrent.ConcurrentHashMap[String,String]().asScala.put("abc","def")    
like image 179
Sascha Kolberg Avatar answered Sep 24 '22 04:09

Sascha Kolberg