GroovyのLongとInteger
Groovy で、partition by parity を解いている時に、またちょっと、うざい挙動にぶちあたった。
m="10 11 12".split()*.toLong().groupBy{it%2} println"$m" //-> [0:[10, 12], 1:[11]] println"${m[0]}" //-> null println"${m[1]}" //-> null
となる。なんで、null なの?しばらく悩んだ。
答えは、
println"${m[0L]}" //-> [10, 12] println"${m[1L]}" //-> [11]
ということ。つまり、マップの key が Integer オブジェクトではなく、Long オブジェクトになっているためだ。int と long の計算を行うときは、long にプロモートされるということがあるが、ここでは、そういった動きは無い。単にタイプの異なるオブジェクトが key になっているということらしい。
なお、これは、Groovy ではなく、Java の挙動だった。
public static void main(String[]a){ Map m=new HashMap(); m.put(0L, 500); System.out.println(m.get(0)); //-> (nothing) System.out.println(m.get(0L)); //-> 500 }
しかも、
public static void main(String[]a){ Map<Long,Long>m=new HashMap<Long,Long>(); m.put(0, 500); //-> Syntax Error m.put(0L, 500L); //-> OK }
だ。オブジェクト間にプロモーションという考えはありえないのか?まぁ、long と Long があるところですでに気持ちよくはないな。因みに、
[1:10, 1L:20, 1g:30, (1 as short):40] //-> [1:10, 1:20, 1:30, 1:40]
となる。そのくせ、
[1, 1L, 1g, 1 as short].unique() //-> [1]
となる。