java 没有值的Java哈希图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/855576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java hashmaps without the value?
提问by jbu
Let's say I want to put words in a data structure and I want to have constant time lookups to see if the word is in this data structure. All I want to do is to see if the word exists. Would I use a HashMap(containsKey()) for this? HashMaps use key->value pairings, but in my case I don't have a value. Of course I could use null for the value, but even null takes space. It seems like there ought to be a better data structure for this application.
假设我想将单词放入数据结构中,并且我想要持续时间查找以查看单词是否在此数据结构中。我只想看看这个词是否存在。我会HashMap为此使用(containsKey()) 吗? HashMaps 使用键-> 值配对,但在我的情况下我没有值。当然,我可以使用 null 作为值,但即使是 null 也需要空间。这个应用程序似乎应该有一个更好的数据结构。
The collection could potentially be used by multiple threads, but since the objects contained by the collection would not change, I do not think I have a synchronization/concurrency requirement.
该集合可能会被多个线程使用,但由于该集合包含的对象不会改变,所以我认为我没有同步/并发要求。
Can anyone help me out?
谁能帮我吗?
回答by Dan Lew
回答by NamshubWriter
You probably want to use a java.util.Set. Implementations include java.util.HashSet, which is the Set equivalent of HashMap.
您可能想要使用java.util.Set。实现包括java.util.HashSet,它是 HashMap 的 Set 等价物。
Even if the objects contained in the collection do not change, you may need to do synchronization. Do new objects need to be added to the Set after the Set is passed to a different thread? If so, you can use Collections.synchronizedSet()to make the Set thread-safe.
即使集合中包含的对象没有改变,您也可能需要进行同步。Set传递给不同的线程后,是否需要将新对象添加到Set中?如果是这样,您可以使用Collections.synchronizedSet()使 Set 线程安全。
If you have a Map with values, and you have some code that just wants to treat the Map as a Set, you can use Map.entrySet() (though keep in mind that entrySet returns a Set view of the keys in the Map; if the Map is mutable, the Map can be changed through the set returned by entrySet).
如果您有一个带值的 Map,并且您有一些代码只想将 Map 视为一个 Set,则可以使用 Map.entrySet()(但请记住,entrySet 返回 Map 中键的 Set 视图;如果 Map 是可变的,则可以通过 entrySet 返回的集合更改 Map)。
回答by Neil Coffey
You'd generally use an implementation of Set, and most usually HashSet. If you did need concurrent access, then ConcurrentHashSet provides a drop-in replacement that provides safe, concurrent access, including safe iteration over the set.
您通常会使用Set的实现,最常见的是 HashSet。如果您确实需要并发访问,那么 ConcurrentHashSet 提供了一个替代品,可提供安全的并发访问,包括对集合的安全迭代。
I'd recommend in any case referring to it as simply a Set throughout your code, except in the one place where you construct it; that way, it's easier to drop in one implementation for the other if you later require it.
在任何情况下,我都建议在您的代码中将其简单地称为 Set,除了在您构造它的一个地方;这样,如果您以后需要,可以更轻松地将一个实现放入另一个实现中。
Even if the set is read-only, if it's used by a thread other than the one that creates it, you do need to think about safe publication(that is, making sure that any other thread sees the set in a consistent state: remember any memory writes, even in constructors, aren't guaranteed to be made available to other threads when or in the otder you expect, unless you take steps to ensure this). This can be done by both of the following:
即使集合是只读的,如果它被创建它的线程以外的线程使用,您确实需要考虑安全发布(即,确保任何其他线程以一致的状态看到集合:记住任何内存写入,即使在构造函数中,也不能保证在您期望的时候或在其他线程中可供其他线程使用,除非您采取措施确保这一点)。这可以通过以下两种方式完成:
- making sure the only reference(s) to the set are in final fields;
- making sure that it really is true that no thread modifies the set.
- 确保对集合的唯一引用在最终字段中;
- 确保没有线程修改集合确实是真的。
You can help to ensure the latter by using the Collections.unmodifiableSet() wrapper. This gives you an unmodifiable view of the given set-- so provided no other "normal" reference to the set escapes, you're safe.
您可以通过使用 Collections.unmodifiableSet() 包装器来帮助确保后者。这为您提供了给定集合的不可修改视图——因此如果没有其他对集合转义的“正常”引用,您是安全的。
回答by Brad B
You want to use a Collection implementing the Set interface, probably HashSet to get the performance you stated. See http://java.sun.com/javase/6/docs/api/java/util/Set.html
您想使用实现 Set 接口的 Collection,可能是 HashSet 来获得您所说的性能。见http://java.sun.com/javase/6/docs/api/java/util/Set.html
回答by Tom Hawtin - tackline
Other than Sets, in some circumstances you might want to convert a Mapinto a Setwith Collections.newSetFromMap(Map<E,Boolean>)(some Maps disallow nullvalues, hence the Boolean).
除了Sets,在某些情况下,您可能希望将 aMap转换为Setwith Collections.newSetFromMap(Map<E,Boolean>)(有些Maps 不允许null值,因此是Boolean)。
回答by pgras
as everyone said HashSet is probably the simplest solution but you won't have constant time lookup in a HashSet (because entries may be chained) and you will store a dummy object (always the same) for every entry...
正如每个人所说的,HashSet 可能是最简单的解决方案,但您不会在 HashSet 中进行恒定时间查找(因为条目可能被链接),并且您将为每个条目存储一个虚拟对象(始终相同)......
For information here a list of data structuresmaybe you'll find one that better fits your needs.

