我有两个包含
的列表List<MyObj>.
和MyObj有一个“String ID”成员。
我需要不时地对它们进行迭代,有时我需要找到两者相似的对象 我想要比列表更快的方式。所以我可以知道我可以使用hashMap (比较时询问包含(String))
我应该使用hashmap还是hashset?
注意:在一个hashset中 - 我需要实现我的equals并且当我运行contains()时 - 我认为它会比hashmap慢,在插入时我把字符串id放在键中。 我是对的吗?
答案 0 :(得分:5)
注意:在一个hashset中 - 我需要实现我的equals并且当我运行contains()时 - 我认为它会比hashmap慢,在插入时我把字符串id放在键中。我是对的吗?
我认为您不会注意到任何性能差异。 HashSet<E>
是使用引擎盖下的HashMap<E, E>
实现的。因此,唯一的区别是调用MyObj.equals()
(可能会调用String.equals()
)与直接调用String.equals()
。 JIT编译器非常擅长内联调用......
最重要的是,您应该(几乎)从不担心微观优化,而是专注于使您的设计简单而一致。如果您唯一关心的是避免重复并检查遏制,Set
是更合理的选择。
答案 1 :(得分:2)
这根本没有什么区别,因为当您查看JDK源代码时,HashSet
的Sun实现在内部使用HashMap
实例来存储其值:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
......
即使情况并非如此,所有其他答案都不会对性能POV产生任何影响。唯一真正的区别在于,您不需要使用密钥类的equals()
和hashCode()
实现,而是需要编写自己的用于使用Set - 但这些可以像委托给{{1如果id
字段是唯一标识符,则为您的类的字段。
答案 2 :(得分:1)
好吧,使用HashMap,您将被迫以这种方式存储数据:
<ID1><MyObject>
<ID2><MyObject>
这不是最好的方法,因为你已经在MyObject中有了ID字段。
使用HashSet,您只能存储MyObject的唯一实例,并且还需要在MyObject中实现hashCode()。
由你来决定。