将数据作为键存储在具有空/空值的HashMap中是一个好主意吗?

时间:2016-08-01 05:17:49

标签: java arrays performance hashmap asymptotic-complexity

我最初写了ArrayList并在其中存储了唯一值(用户名,即Strings)。我后来需要使用ArrayList来搜索用户是否存在。那是O(n)的搜索。

我的技术负责人希望我将其更改为HashMap,并将用户名存储为数组中的键,值为空Strings

所以,在Java中 -

hashmap.put("johndoe","");

我稍后可以通过运行

来查看此用户是否存在
hashmap.containsKey("johndoe"); 

这是O(1)对吧?

我的主管说这是一种更有效的方法,这对我来说很有意义,但是在hashmap中将null / empty作为值并将其作为键存储在其中似乎有点过时了。

我的问题是,这是一个好方法吗?效率优于ArrayList#contains或一般的数组搜索。有用。 我担心的是,我没有看到其他人在搜索后这样做。我可能在某个地方错过了一个明显的问题,但我无法看到它。

2 个答案:

答案 0 :(得分:101)

由于您有一组唯一值,因此Set是适当的数据结构。您可以将值放在HashSet Set接口的实现中。

  

我的主管说这是一种更有效的方法,这对我来说很有意义,但是在hashmap中将null / empty作为值并将其作为键存储在其中似乎有点过时了。

领导的建议是有缺陷的。 Map不是Set的正确抽象。MapSet<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)对吗?

是的,在HashSetList中搜索是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是支持HashMapPRESENT是虚拟值。

  

我担心的是,我没有看到其他人在搜索后这样做。我可能在某个地方错过了一个明显的问题,但我无法看到它。

正如我所提到的,JDK的开发人员正在使用相同的方法。