対応付けのキーとセットでのカスタムデータ型の使用
対応付けでは、使用する Apex クラスのインスタンスはキーまたは値のいずれかとして追加できます。ただし、それらをキーとして追加する場合、対応付けが正しく機能してキーによって正しい値がフェッチされるようにするには、クラスで実装する必要のある特別な規則がいくつかあります。同様に、設定要素がカスタムクラスのインスタンスである場合、クラスはこれらと同じ規則に従う必要があります。
対応付けのキーまたはセット要素にカスタムデータ型 (Apex クラス) を使用する場合、クラスで equals メソッドと hashCode メソッドを提供します。Apex はこの 2 つのメソッドを使用して、オブジェクトのキーの等価と一意性を判断します。
クラスへの equals メソッドと hashCode メソッドの追加
- 署名付きの equals メソッドを次に示します。
1public Boolean equals(Object obj) { 2 // Your implementation 3}equals メソッドの実装時には、次の点に留意してください。クラスの x、y、z が null 以外のインスタンスである場合、equals メソッドは次の条件を満たす必要があります。- 反射性: x.equals(x)
- 対称性: x.equals(y) は、y.equals(x) が true を返す場合にのみ true を返す
- 推移性: x.equals(y) が true を返し、かつ y.equals(z) が true を返す場合、x.equals(z) は true を返す
- 整合性: x.equals(y) の複数の呼び出しで常に true を返すか常に false を返す
- null 以外の参照値 x では、x.equals(null) は false を返す
Apex の equals メソッドは、Java の equals メソッドに基づいています。
- 署名付きの hashCode メソッドを次に示します。
1public Integer hashCode() { 2 // Your implementation 3}hashCode メソッドの実装時には、次の点に留意してください。- hashCode メソッドが Apex 要求の実行中に同じオブジェクトで複数回呼び出された場合、同じ値を返す必要がある
- equals メソッドで 2 つのオブジェクトが等価とされた場合、hashCode は同じ値を返す必要がある
- equals メソッドで 2 つのオブジェクトが等価でないとされた場合、hashCode は異なる値を返す必要はない
Apex の hashCode メソッドは、Java の hashCode メソッドに基づいています。
1// obj1 and obj2 are instances of MyClass
2if (obj1 == obj2) {
3 // Do something
4}
5
6if (obj1.equals(obj2)) {
7 // Do something
8}サンプル
このサンプルでは、equals メソッドと hashCode メソッドの実装方法を示します。これらのメソッドを提供するクラスが最初に表示されています。2 つの Integer を取るコンストラクタも含まれています。2 番目のサンプルはコードスニペットで、このクラスの 3 つのオブジェクトを作成し、そのうち 2 つは値が同じです。次に、ペアオブジェクトをキーとして使用して対応付けエントリが追加されます。最後に追加されたエントリには最初のエントリと同じキーが含まれているため、最初のエントリが上書きされ、サンプルでは対応付けに 2 つのエントリのみが存在することが確認されます。次に、== 演算子を使用します。クラスは equals を実装するため、この演算子は期待どおりに機能します。また、対応付けに特定のキーが含まれているかどうかの確認、デバッグログへのすべてのキーと値の書き込みなど、その他のいくつかの対応付け操作が実行されます。最後に、セットを作成してそのセットに同じオブジェクトを追加します。3 つのオブジェクトのうち 2 つのみが一意であるため、セットのサイズが 2 であることを確認します。
1public class PairNumbers {
2 Integer x,y;
3
4 public PairNumbers(Integer a, Integer b) {
5 x=a;
6 y=b;
7 }
8
9 public Boolean equals(Object obj) {
10 if (obj instanceof PairNumbers) {
11 PairNumbers p = (PairNumbers)obj;
12 return ((x==p.x) && (y==p.y));
13 }
14 return false;
15 }
16
17 public Integer hashCode() {
18 return (31 * x) ^ y;
19 }
20}このコードスニペットは PairNumbers クラスを使用します。
1Map<PairNumbers, String> m = new Map<PairNumbers, String>();
2PairNumbers p1 = new PairNumbers(1,2);
3PairNumbers p2 = new PairNumbers(3,4);
4// Duplicate key
5PairNumbers p3 = new PairNumbers(1,2);
6m.put(p1, 'first');
7m.put(p2, 'second');
8m.put(p3, 'third');
9
10// Map size is 2 because the entry with
11// the duplicate key overwrote the first entry.
12System.assertEquals(2, m.size());
13
14// Use the == operator
15if (p1 == p3) {
16 System.debug('p1 and p3 are equal.');
17}
18
19// Perform some other operations
20System.assertEquals(true, m.containsKey(p1));
21System.assertEquals(true, m.containsKey(p2));
22System.assertEquals(false, m.containsKey(new PairNumbers(5,6)));
23
24for(PairNumbers pn : m.keySet()) {
25 System.debug('Key: ' + pn);
26}
27
28List<String> mValues = m.values();
29System.debug('m.values: ' + mValues);
30
31// Create a set
32Set<PairNumbers> s1 = new Set<PairNumbers>();
33s1.add(p1);
34s1.add(p2);
35s1.add(p3);
36
37// Verify that we have only two elements
38// since the p3 is equal to p1.
39System.assertEquals(2, s1.size());