Может ли Java-массив использоваться как ключ HashMap
Если ключ HashMap является строковым массивом:
HashMap<String[], String> pathMap;
Можно ли получить доступ к карте с помощью вновь созданного массива строк или же он должен быть тем же объектом String []?
pathMap = new HashMap<>(new String[] { "korey", "docs" }, "/home/korey/docs");
String path = pathMap.get(new String[] { "korey", "docs" });
Ответы
Ответ 1
Это должен быть тот же объект. A 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"));
Ответ 2
Нет, но вы можете использовать List<String>
, который будет работать так, как вы ожидаете!
Ответ 3
Массивы в Java используют Object
hashCode()
и не переопределяют его (то же самое с equals()
и toString()
). Так что нет, вы не можете не использовать массивы в качестве ключа hashmap.
Ответ 4
Тед Хопп прав, он должен быть тем же самым объектом
для информации см. этот пример
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".
Ответ 5
Вы не можете использовать простой Java Array
в качестве ключа в HashMap
. (Ну, вы можете, но это не сработает, как ожидалось.)
Но вы могли бы написать класс-оболочку, который имеет ссылку на массив, а также переопределяет hashCode()
и equals()
.
Ответ 6
В большинстве случаев, когда строки внутри вашего массива не являются патологическими и не включают запятые, за которыми следует пробел, вы можете использовать Arrays.toString()
как уникальный ключ. т.е. ваш Map
будет Map<String, T>
. И get/put для массива myKeys[]
будет
T t = myMap.get(Arrays.toString(myKeys));
myMap.put(Arrays.toString(myKeys), myT);
Очевидно, вы могли бы поместить код оболочки, если хотите.
Хороший побочный эффект заключается в том, что ваш ключ теперь неизменен. Конечно, вы меняете свой массив myKeys, а затем попробуйте get()
, вы его не найдете.
Хеширование строк сильно оптимизировано. Поэтому я предполагаю, что это решение, хотя и немного медленное и клочковое, будет быстрее и эффективнее с точки зрения памяти (меньше распределений объектов), чем решение @Ted Hopp, используя неизменный список. Просто подумайте о том, является ли Arrays.toString()
уникальным для ваших ключей. Если нет, или если есть какие-либо сомнения (например, String [] поступает от пользовательского ввода), используйте Список.