Хорошо ли хранить данные в виде ключей в HashMap с пустыми/нулевыми значениями?
Я изначально написал ArrayList
и сохранил уникальные значения (имена пользователей, т.е. Strings
). Позднее мне понадобилось использовать ArrayList
для поиска, если пользователь существовал в нем. Это O(n)
для поиска.
Мой технический руководитель хотел, чтобы я изменил его на HashMap
и сохранил имена пользователей как ключи в массиве, а значения пустые Strings
.
Итак, в Java -
hashmap.put("johndoe","");
Я вижу, существует ли этот пользователь позже, выполнив -
hashmap.containsKey("johndoe");
Это O(1)
правильно?
Мой руководитель сказал, что это был более эффективный способ сделать это, и это имело смысл для меня, но мне показалось, что это немного пошло, чтобы поместить null/empty в качестве значений в hashmap и сохранить в нем элементы как ключи.
Мой вопрос в том, хороший подход? Эффективность превосходит ArrayList#contains
или поиск массива в целом. Оно работает.
Мое беспокойство заключается в том, что я не видел, чтобы кто-то еще делал это после обыска. Возможно, я не вижу очевидной проблемы, но я не вижу ее.
Ответы
Ответ 1
Поскольку у вас есть набор уникальных значений, Set
- соответствующая структура данных. Вы можете поместить свои значения в HashSet
, реализацию интерфейса Set
.
Мой руководитель сказал, что это был более эффективный способ сделать это, и это имело смысл для меня, но мне показалось, что это немного пошло, чтобы поместить null/empty в качестве значений в hashmap и сохранить в нем элементы как ключи.
Совет по свинцу является ошибочным. Map
не является правильной абстракцией для этого, Set
is. A Map
подходит для пар ключ-значение. Но у вас нет значений, только ключей.
Пример использования:
Set<String> users = new HashSet<>(Arrays.asList("Alice", "Bob"));
System.out.println(users.contains("Alice"));
// -> prints true
System.out.println(users.contains("Jack"));
// -> prints false
Использование Map
было бы неудобным, потому что какой должен быть тип значений? Этот вопрос не имеет смысла в вашем случае использования,
поскольку у вас есть только ключи, а не пары ключ-значение.
С Set
вам не нужно спрашивать об этом, использование совершенно естественно.
Это O (1) правильно?
Да, поиск в HashMap
или HashSet
является O (1) амортизированным наихудшим случаем, тогда как поиск в List
или в массиве - это O (n) наихудший случай.
В некоторых комментариях указывается, что a HashSet
реализуется в терминах HashMap
.
Это прекрасно, на этом уровне абстракции.
На уровне абстракции задачи под рукой ---
для хранения коллекции уникальных имен пользователей,
использование набора является естественным выбором, более естественным, чем карта.
Ответ 2
В основном это реализация HashSet
, поэтому, я думаю, вы можете сказать, что это хороший подход. Вы можете использовать HashSet
вместо HashMap
с пустыми значениями.
Например:
HashSet
реализация add
-
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
где map
- это поддержка HashMap
, а PRESENT
- фиктивное значение.
Мое беспокойство заключается в том, что я не видел, чтобы кто-то еще делал это после поиска. Возможно, я не вижу очевидной проблемы, но я не вижу ее.
Как я уже упоминал, разработчики JDK используют этот же подход.