将数据存储为HashMap中具有空值/空值的键是个好主意吗?
我原来写了一个ArrayList
并在其中存储了唯一的值(用户名,即Strings
)。 我后来需要使用ArrayList
来search用户是否存在。 这是O(n)
的search。
我的技术负责人希望我将其更改为HashMap
,并将用户名作为键存储在数组中,并将值存储为空Strings
。
所以,在Java中 –
hashmap.put("johndoe","");
我可以看到这个用户以后是否存在运行 –
hashmap.containsKey("johndoe");
这是O(1)
对不对?
我的领导说这是一个更有效的方式来做到这一点,这对我来说是有道理的,但是在hashmap中存储null / empty作为值并将其作为关键字存储在元素中似乎有点不合适。
我的问题是,这是一个好方法吗? 通常, ArrayList#contains
的效率或数组search。 有用。 我的担心是,我没有看到任何人在search后做这个。 我可能在某个地方错过了一个显而易见的问题,但我看不到它。
由于您有一组唯一的值,因此Set
是适当的数据结构。 你可以把你的值放在HashSet
,这是Set
接口的一个实现。
我的领导说这是一个更有效的方式来做到这一点,这对我来说是有道理的,但是在hashmap中存储null / empty作为值并将其作为关键字存储在元素中似乎有点不合适。
领导的build议是有缺陷的。 Map
不是这个的正确抽象, Set
是。 一个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
会很尴尬,因为应该是什么types的值? 这个问题在你的用例中没有意义,因为你只有键,而不是键 – 值对。 有了Set
,你不需要问,这个用法是完全自然的。
这是O(1)对不对?
是的,在HashMap
或者HashSet
search是O(1)最坏情况,而在List
或者数组中search最坏的情况是O(n)。
有些评论指出HashSet
是用HashMap
来实现的。 没关系, 在抽象层面 。 在手头任务的抽象层面—存储一组唯一的用户名,使用一组是一个自然的select,比地图更自然。
这基本上是如何实现HashSet
,所以我想你可以说这是一个好方法。 你也可以使用HashSet
而不是HashMap
的空值。
例如 :
HashSet
的add
的实现是
public boolean add(E e) { return map.put(e, PRESENT)==null; }
其中map
是后台HashMap
和PRESENT
是虚拟值。
我的担心是,我没有看到任何人在search后做这个。 我可能在某个地方错过了一个显而易见的问题,但我看不到它。
正如我所提到的,JDK的开发人员正在使用相同的方法。