Can a java array be used as a HashMap key

2019-01-02 23:50发布

If a HashMap's key is a string array:

HashMap<String[], String> pathMap;

Can you access the map by using a newly created string array or does it have to be the same String[] object?

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

6条回答
冷血范
2楼-- · 2019-01-03 00:19

It will have to be the same object. A HashMap compares keys using equals() and two arrays in Java are equal only if they are the same object.

If you want value equality, then write your own container class that wraps a String[] and provides the appropriate semantics for equals() and hashCode(). In this case, it would be best to make the container immutable, as changing the hash code for an object plays havoc with the hash-based container classes.

EDIT

As others have pointed out, List<String> has the semantics you seem to want for a container object. So you could do something like this:

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"));
查看更多
Anthone
3楼-- · 2019-01-03 00:24

Ted Hopp is right it will have to be same object

for information see this example

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

When you run above it will print "docs".

查看更多
时光不老,我们不散
4楼-- · 2019-01-03 00:34

Arrays in Java use Object's hashCode() and don't override it (the same thing with equals() and toString()). So no, you cannot shouldn't use arrays as a hashmap key.

查看更多
等我变得足够好
5楼-- · 2019-01-03 00:37

No, but you can use List<String> which will work as you expect!

查看更多
叛逆
6楼-- · 2019-01-03 00:39

You cannot use a plain Java Array as a key in a HashMap. (Well you can, but it won't work as expected.)

But you could write a wrapper class that has a reference to the Array and that also overrides hashCode() and equals().

查看更多
我欲成王,谁敢阻挡
7楼-- · 2019-01-03 00:39

In most cases, where the Strings inside your array are not pathological and do not include commas followed by a space, you can use Arrays.toString() as a unique key. i.e. your Map would be a Map<String, T>. And the get/put for an array myKeys[] would be

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

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

Obviously you could put in some wrapper code if desired.

A nice side effect is that your key is now immutable. Of course, of you change your array myKeys and then try a get(), you won't find it.

Hashing of Strings is highly optimized. So my guess is that this solution, though it feels a bit slow and kludgy, will be both faster and more memory efficient (less object allocations) than @Ted Hopp solution using an immutable List. Just think about whether Arrays.toString() is unique for your keys. If not, or if there is any doubt, (e.g. the String[] comes from user input) use the List.

查看更多
登录 后发表回答