Подтвердить что ты не робот

Может ли 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" });
4b9b3361

Ответ 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 [] поступает от пользовательского ввода), используйте Список.