可以将java数组用作HashMap键

时间:2013-05-30 14:44:28

标签: java hashmap arrays

如果HashMap的键是字符串数组:

HashMap<String[], String> pathMap;

您可以使用新创建的字符串数组访问地图,还是必须是相同的String []对象?

pathMap = new HashMap<>(new String[] { "korey", "docs" }, "/home/korey/docs");
String path = pathMap.get(new String[] { "korey", "docs" });

8 个答案:

答案 0 :(得分:35)

它必须是同一个对象。 HashMap使用equals()比较密钥,而Java中的两个数组只有在它们是同一个对象时才相等。

如果你想要值相等,那么编写你自己的包装String[]的容器类,并为equals()hashCode()提供适当的语义。在这种情况下,最好使容器不可变,因为更改对象的哈希代码会对基于哈希的容器类造成严重破坏。

修改

正如其他人所指出的那样,List<String>具有您似乎想要容器对象的语义。所以你可以这样做:

HashMap<List<String>, String> pathMap;

pathMap.put(
    // unmodifiable so key cannot change hash code
    Collections.unmodifiableList(Arrays.asList("korey", "docs")),
    "/home/korey/docs"
);

// later:
String dir = pathMap.get(Arrays.asList("korey", "docs"));

答案 1 :(得分:6)

不,但您可以使用List<String>,它可以正常运作!

答案 2 :(得分:1)

Java中的数组使用Object的{​​{1}}并且不会覆盖它(与hashCode()equals()相同)。所以不,你不能不应该使用数组作为hashmap键。

答案 3 :(得分:1)

Ted Hopp是对的,它必须是同一个对象

有关信息,请参阅此示例

public static void main(String[] args) {
        HashMap<String[], String> pathMap;
        pathMap = new HashMap<String[], String>();
        String[] data = new String[] { "korey", "docs" };
        pathMap.put(data, "/home/korey/docs");
        String path = pathMap.get(data);
        System.out.println(path);
    }
}

当你在上面跑步时,它将打印“docs”。

答案 4 :(得分:1)

您不能将普通Java Array用作HashMap中的密钥。 (嗯,你可以,但它不会按预期工作。)

但是你可以写一个包含类的引用类,它也会覆盖hashCode()equals()

答案 5 :(得分:0)

在大多数情况下,如果数组中的字符串不是病态的,并且不包含逗号后跟空格,则可以使用Arrays.toString()作为唯一键。即,您的Map将是Map<String, T>。数组myKeys[]的get / put将是

T t = myMap.get(Arrays.toString(myKeys));

myMap.put(Arrays.toString(myKeys), myT);

显然,如果需要,你可以输入一些包装代码。

一个好的副作用是你的密钥现在是不可变的。当然,你更改你的数组myKeys,然后尝试get(),你将找不到它。

Hashing of Strings得到了高度优化。所以我的猜测是这个解决方案虽然感觉有点慢和kludgy,但它比使用不可变List的@Ted Hopp解决方案更快,内存效率更高(更少的对象分配)。只需考虑Arrays.toString()对于您的密钥是否唯一。如果没有,或者有任何疑问,(例如String []来自用户输入)请使用List。

答案 6 :(得分:0)

使用Arrays实用程序及其提供的哈希码的运行示例:

String[] key1 = { "korey", "docs" };
String value1 = "/home/korey/docs";
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(Arrays.hashCode(key1), value1);
System.out.println(map);

{-1122550406 = / home / korey / docs}

如果您的重点仅在于存储,则此方法很有用。使用可读(原始)键进行检索很简单:

String retrievedValue = map.get(Arrays.hashCode(key1));
System.out.println(retrievedValue);

/ home / korey / docs

答案 7 :(得分:0)

Java 9 开始,您可以使用 Arrays::compare 方法作为 TreeMap 的比较器,用于比较数组的内容

Map<String[], String> map = new TreeMap<>(Arrays::compare);

String[] key1 = {"one", "two"};
String[] key2 = {"one", "two"};
String[] key3 = {"one", "two"};

map.put(key1, "value1");
map.put(key2, "value2");

System.out.println(map.size()); // 1
System.out.println(map.get(key1)); // value2
System.out.println(map.get(key2)); // value2
System.out.println(map.get(key3)); // value2

另见:How to make a Set of arrays in Java?