2016-07-08 3 views
0

Groovyでキーを変更できないクラスのインスタンスにするマップを使用したいと思います。GroovyとJavaのカスタムキーを使ったマップ

これは、私はJavaで頻繁に行うものです、それは、この例のクラスのように、正常に動作します:

public class TestMap { 
    static final class Point { 
     final int x; final int y; 
     public Point(int x, int y) {this.x = x;this.y = y;} 
    } 

    public static void main(String[] args) { 
     Map<Point, String> map = new HashMap<>(); 
     final Point origin = new Point(0, 0); 
     map.put(origin, "hello world !"); 
     if(!map.containsKey(origin)) 
      throw new RuntimeException("can't find key origin in the map"); 
     if(!map.containsKey(new Point(0,0))) { 
      throw new RuntimeException("can't find new key(0,0) in the map"); 
     } 
    } 
} 

をしかし、私はGroovyのと同じことを達成しようとすると、それは動作しません。 なぜですか?あなたはインスタンスはあなたが行うことができますHashMap

にキーとして見ることができるようにPointクラスにequalshashCode方法を持っている必要があります

class Point { 
    final int x; final int y 
    Point(int x, int y) { this.x = x; this.y = y } 
    public String toString() { return "{x=$x, y=$y}" } 
} 

def origin = new Point(0, 0) 
def map = [(origin): "hello"] 
map[(new Point(1,1))] = "world" 
map.put(new Point(2,2), "!") 

assert map.containsKey(origin) // this works: when it's the same ref 
assert map.containsKey(new Point(0,0)) 
assert map.containsKey(new Point(1,1)) 
assert map.containsKey(new Point(2,2)) 
assert !map.containsKey(new Point(3,3)) 
+0

Javaバージョンも機能しません。 [here](https://ideone.com/hUsD2H)を参照してください。 – Ironcache

答えて

5

:ここ はGroovyでサンプル以外の実施例でありますGroovyでアノテーションを追加することで素早くアノテーションを追加できます。

import groovy.transform.* 

@EqualsAndHashCode 
class Point { 
    final int x; final int y 
    Point(int x, int y) { this.x = x; this.y = y } 
    public String toString() { return "{x=$x, y=$y}" } 
} 
+0

それはなぜJavaの箱の外で働くのですか? – Guillaume

+0

それはありません。 'equals()'と 'hashCode()'も必要です。 JavaコードがRuntimeExceptionをスローする理由は、マップ内に新しいキー(0,0)が見つかりません。 – Andreas

+0

Andreasが正しいです。与えられたJavaコードは、私が質問にコメントした[example output](https://ideone.com/hUsD2H)に示されているように、妥協したマップを作成します。これは正解です。 – Ironcache

関連する問題