4

As the code shows:

val map = scala.collection.mutable.Map[Int, Int]().withDefaultValue(0)
println(map(1))
map(1) = 10
println(map(1))
map(1) += 10
println(map(1))

and the output:

0
10
20

However, in my opinion, "map(1) += 10" is invalid as in java, and even valid, the result after this line, map(1) should be 10.

So Why??? and what exactly operation "+=" do in map ??

CodeBoy
  • 591
  • 6
  • 12
  • 3
    Possible duplicate of [How does Scala's mutable Map update \[map(key) = newValue\] syntax work?](http://stackoverflow.com/questions/15604697/how-does-scalas-mutable-map-update-mapkey-newvalue-syntax-work) – Noah Dec 22 '15 at 03:20
  • I don't understand why you think that "the result after this line, map(1) should be 10" – Jasper-M Dec 22 '15 at 15:25

3 Answers3

6

First, += is an assignment operator, because it ends in = and isn't a comparison operator. This means that if there is no suitable method (and Int doesn't have a += method), map(1) += 10 is converted to map(1) = map(1) + 10. By the rules in Assignments, this becomes map.update(1, map(1) + 10) and this becomes map.update(1, map.apply(1) + 10) because map is an object rather than a method.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
3

The question asked 'what exactly operation "+=" do in map ??' is not relevant to the situation you described. Map's method += adds entry (key -> value) to Map, so that map(key) == value.

So the question is: what does map(1) += 10 does.

This simple lines

  map(1) += 10

compiles into this javacode

  24: invokestatic  #36                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  27: aload_2
  28: iconst_1
  29: invokestatic  #36                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  32: invokeinterface #43,  2           // InterfaceMethod scala/collection/mutable/Map.apply:(Ljava/lang/Object;)Ljava/lang/Object;
  37: invokestatic  #47                 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  40: bipush        10
  42: iadd
  43: invokestatic  #36                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  46: invokeinterface #51,  3           // InterfaceMethod scala/collection/mutable/Map.update:(Ljava/lang/Object;Ljava/lang/Object;)V

Remove boxing and unboxing ops - we are not interested in them(line 24, 29, 37, 43). Review the rest:

We get value that was in map

  27: aload_2
  28: iconst_1
  32: invokeinterface #43,  2           // InterfaceMethod scala/collection/mutable/Map.apply:(Ljava/lang/Object;)Ljava/lang/Object;

Add 10 to it:

  40: bipush        10
  42: iadd

And accomplish update:

  46: invokeinterface #51,  3           // InterfaceMethod scala/collection/mutable/Map.update:(Ljava/lang/Object;Ljava/lang/Object;)V

Seems map(1) += 10 is desugared to map.update(1, map.apply(1) + 10)

nikiforo
  • 426
  • 3
  • 7
0

In Scala Map. += means

ms += (k -> v)  Adds mapping from key k to value v to map ms as a side effect and returns ms itself.

ms += (k -> v, l -> w)  Adds the given mappings to ms as a side effect and returns ms itself.
Vignesh Kumar A
  • 27,863
  • 13
  • 63
  • 115