Java LinkedHashMap containsKey或containsValue

Java LinkedHashMap containsKey或containsValue,java,linkedhashmap,Java,Linkedhashmap,为什么会发生这种情况?我如何避免? 我想它只是检查参考资料,但这不是很方便 import java.util.LinkedHashMap; public class CheckingLinkedHashMap { public static void main(String[] args) { LinkedHashMap<String[], String[]> linkedh = new LinkedHashMap<>(); S

为什么会发生这种情况?我如何避免? 我想它只是检查参考资料,但这不是很方便

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));
    }
}

更新
这似乎有效。我想我必须做一些额外的检查,以避免密钥重复。

containsKey和
containsValue
函数可能在
equals()
和/或
hashCode()
方面工作。对于
String[]
,正如您正确指出的,这些可能是参考术语。除非您可以将比较器与
containsKey()
containsValue()
一起传递,否则您可以选择创建自己的类,该类执行
String[]
所做的操作,但它可以计算
equals()
hashCode()
以使具有相同值的对象相等的方式。

问题在于您使用的数组默认情况下通过引用进行相等比较。要解决问题,应将它们封装到类中并重写相应的方法:

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()
,否则您将无法在哈希容器中成功使用此类。请注意,
数组。hashCode
进行浅层hashCode计算,这不适用于嵌套数组。

您得到了期望的结果,您的问题是什么???@gangnamstyleoverflowerr否期望的结果是有四个
true
,我想问是否有方法检查值而不是引用。也许我的问题还不够清楚。我怎样才能通过一个比较器?你能提供一些示例代码吗?@yannishristofakis除非Java API允许这样做(不要认为它允许,但我没有检查),否则你不能。抱歉给人的印象是我认为这是一种现实的可能性。更好的是,只使用
列表
,和
数组。asList
?@LouisWasserman我不明白,你是说用
列表
代替
字符串
数组还是用
哈希映射
?这能满足我的需要吗(第一个)?我是说用
List
代替
String[]
,用
数组将
String[]
转换成
List
。asList
,当然它能满足你的需要。@Yannishristofaki是的,只要把
String[]包装一下就行了
列表中
使用
数组。asList
@yannishristofakis:我猜他说的是
HashMap
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
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);
  }
}