我对Java中的数据结构有疑问。在解决Java中的典型哈希问题时,我使用的是 HashSet
数据结构,这种结构很好,直到有重复的对象(对象内容)。由于HashSet不支持插入重复项,因此我的逻辑失败了。
我将hashset替换为典型的 Arraylist
,因为hashset的方法如 .add(), .contains()两者都支持em>, .remove(),然后我的逻辑就完美了。
但这是否必然意味着当涉及重复时,ArrayList是Hashset的合理选择? Hashset应该有一些时间复杂性优于ArrayList吗?有人可以就此提供一些见解吗?
编辑:当您想要在涉及重复时进行散列时,理想的数据结构是什么。我的意思是不应该忽略重复项并且应该插入。
答案 0 :(得分:4)
不清楚你的散列问题是什么意思,"但也许你正在寻找multiset。来自Guava文档:
支持与顺序无关的相等性的集合,如Set,但可能包含重复的元素。 multiset有时也被称为包。
多个集合中彼此相等的元素称为相同单个元素的出现。多集中元素的出现次数称为该元素的计数(术语"频率"和"多样性"等效,但未在此API中使用)。 / p>
JDK中不存在这样的东西。
答案 1 :(得分:2)
这完全取决于您的需求。
答案 2 :(得分:2)
ArrayList
不是合乎逻辑的选择。针对不同用例的不同工具。
您可以在重复项无意义的区域使用Set
,例如,一组学生。 List
允许重复。
答案 3 :(得分:0)
如果您特别需要处理重复项的HashSet
,HashMap
将能够完成这项工作。如果您只需要计算添加的对象数(使用快速查找/等),HashMap<T,Integer>
将是理想的,其中T
是您的对象的类型。如果您确实需要保留对已添加的重复对象的引用,请使用HashMap<T, List<T>>
。这样,您可以使用HashMap的.containsKey(T t)
进行查找,并遍历结果列表中的所有类似哈希对象。例如,您可以创建此类:
public class HashSetWithDuplicates<T> {
private HashMap<T, List<T>> entries;
private int size;
public HashSetWithDuplicates(){
entries = new HashMap<>();
size = 0;
}
public HashSetWithDuplicates(Collection<? extends T> col){
this();
for(T t : col){
add(t);
}
}
public boolean contains(T t){
return entries.containsKey(t);
}
public List<T> get(T t){
return entries.get(t);
}
public void add(T t){
if (!contains(t)) entries.put(t, new ArrayList<>());
entries.get(t).add(t);
size++;
}
public void remove(T t){
if (!contains(t)) return;
entries.get(t).remove(t);
if(entries.get(t).isEmpty()) entries.remove(t);
size--;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size() == 0;
}
}
根据您的需要添加功能。