我最初写了ArrayList
并在其中存储了唯一值(用户名,即Strings
)。我后来需要使用ArrayList
来搜索用户是否存在。那是O(n)
的搜索。
我的技术负责人希望我将其更改为HashMap
,并将用户名存储为数组中的键,值为空Strings
。
所以,在Java中 -
hashmap.put("johndoe","");
我稍后可以通过运行
来查看此用户是否存在hashmap.containsKey("johndoe");
这是O(1)
对吧?
我的主管说这是一种更有效的方法,这对我来说很有意义,但是在hashmap中将null / empty作为值并将其作为键存储在其中似乎有点过时了。
我的问题是,这是一个好方法吗?效率优于ArrayList#contains
或一般的数组搜索。有用。
我担心的是,我没有看到其他人在搜索后这样做。我可能在某个地方错过了一个明显的问题,但我无法看到它。
答案 0 :(得分:101)
由于您有一组唯一值,因此Set
是适当的数据结构。您可以将值放在HashSet
Set
接口的实现中。
我的主管说这是一种更有效的方法,这对我来说很有意义,但是在hashmap中将null / empty作为值并将其作为键存储在其中似乎有点过时了。
领导的建议是有缺陷的。 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
使用Set
会很尴尬,因为值应该是什么类型?这个问题对你的用例毫无意义,
因为你只有键,而不是键值对。
使用HashMap
,您无需询问,使用情况非常自然。
这是O(1)对吗?
是的,在HashSet
或List
中搜索是O(1)摊销的最坏情况,而在HashSet
或数组中搜索是最坏情况的O(n)。< / p>
有些评论指出,HashMap
是按Jimp.read("test.jpg", function (err, test) {
if (err) throw err;
test.resize(256, 256)
.quality(50)
.write(__dirname + "./new.jpg");
});
实施的。
那很好,在那个抽象层。
在手头的任务抽象层面---
存储一组唯一的用户名,
使用集合是一种自然的选择,比地图更自然。
答案 1 :(得分:36)
这基本上是HashSet
的实施方式,所以我想你可以说这是一个很好的方法。您也可以使用HashSet
代替HashMap
空值。
例如:
HashSet
add
的实施是
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
其中map
是支持HashMap
,PRESENT
是虚拟值。
我担心的是,我没有看到其他人在搜索后这样做。我可能在某个地方错过了一个明显的问题,但我无法看到它。
正如我所提到的,JDK的开发人员正在使用相同的方法。