2

なぜこれが起こっているのですか、どうすれば回避できますか? 参照をチェックするだけだと思いますが、それはあまり便利ではありません。

import java.util.LinkedHashMap;

public class CheckingLinkedHashMap {

    public static void main(String[] args) {
        LinkedHashMap<String[], String[]> linkedh = new LinkedHashMap<>();
        String[] a = "A".split(",");
        String[] ab = "A,B".split(",");
        linkedh.put(a, ab);
        String[] aa = "A".split(",");
        String[] aabb = "A,B".split(",");
        System.out.println("Contains key: " + linkedh.containsKey(aa));
        System.out.println("Contains value: " + linkedh.containsValue(aabb));

        System.out.println("Contains key: " + linkedh.containsKey(a));
        System.out.println("Contains value: " + linkedh.containsValue(ab));
    }
}

--

Contains key: false
Contains value: false
Contains key: true
Contains value: true

アップデート

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class CheckingLinkedHashMap {

    public static void main(String[] args) {

        LinkedHashMap< List<String>, List<String>> linkedh = new LinkedHashMap<>();

        String[] a = "A".split(",");
        String[] ab = "A,B".split(",");
        List<String> al = Arrays.asList(a);
        List<String> abl = Arrays.asList(ab);
        linkedh.put(al, abl);

        String[] aa = "A".split(",");
        String[] aabb = "A,B".split(",");
        List<String> aal = Arrays.asList(aa);
        List<String> aabbl = Arrays.asList(aabb);
        linkedh.put(aal, aabbl);

        String[] aaa = "A,B".split(",");
        String[] aaabbb = "A,B".split(",");
        List<String> aaal = Arrays.asList(aaa);
        List<String> aaabbbl = Arrays.asList(aaabbb);
        linkedh.put(aaal, aaabbbl);

        String[] aaaa = "B,A".split(",");
        String[] aaaabbbb = "A,B".split(",");
        List<String> aaaal = Arrays.asList(aaaa);
        List<String> aaaabbbbl = Arrays.asList(aaaabbbb);
        linkedh.put(aaaal, aaaabbbbl);

        Iterator it = linkedh.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pairs = (Map.Entry) it.next();
            System.out.println("Key : " + pairs.getKey() + " Value : " + pairs.getValue());
        }

        System.out.println("Contains key: " + linkedh.containsKey(aal));
        System.out.println("Contains value: " + linkedh.containsValue(aabbl));

        System.out.println("Contains key: " + linkedh.containsKey(al));
        System.out.println("Contains value: " + linkedh.containsValue(abl));
    }
}

--

Key : [A] Value : [A, B]
Key : [A, B] Value : [A, B]
Key : [B, A] Value : [A, B]
Contains key: true
Contains value: true
Contains key: true
Contains value: true

これは機能しているようです。キーの重複を避けるために、追加のチェックを行う必要があると思います。

4

2 に答える 2

4

問題は、デフォルトで参照によって等しいかどうか比較される配列を使用していることです。問題を解決するには、それらをクラスにカプセル化し、適切なメソッドをオーバーライドする必要があります。

class StringBundle {
  String[] strings;

  @Override
  public boolean equals(Object o) {
    // various checks
    return Array.deepEquals(this.strings, o.strings);
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(strings);
  }
}

独自のバージョンのも提供する方法が必要です。hashCode()そうしないと、ハッシュされたコンテナー内でこのクラスを正常に使用できなくなります。ネストArrays.hashCodeされた配列には適していない浅いハッシュコード計算を行うことに注意してください。

于 2013-01-04T22:19:34.373 に答える
3

containsKeyand関数は、おそらくand/orcontainsValueに関して機能します。あなたが正しく指摘しているように、これらはおそらく参照の観点からです。andとともにコンパレータを渡すことができない限り、同じ値を持つオブジェクトが等しい方法でandを計算できることを除いて、何をするかを行う独自のクラスを作成するオプションになります。equals()hashCode()String[]containsKey()containsValue()String[]equals()hashCode()

于 2013-01-04T22:17:44.703 に答える