HashSet优于ArrayList,反之亦然

时间:2015-07-12 05:57:54

标签: java arraylist hashset

我对Java中的数据结构有疑问。在解决Java中的典型哈希问题时,我使用的是 HashSet 数据结构,这种结构很好,直到有重复的对象(对象内容)。由于HashSet不支持插入重复项,因此我的逻辑失败了。

我将hashset替换为典型的 Arraylist ,因为hashset的方法如 .add() .contains() .remove(),然后我的逻辑就完美了。

但这是否必然意味着当涉及重复时,ArrayList是Hashset的合理选择? Hashset应该有一些时间复杂性优于ArrayList吗?有人可以就此提供一些见解吗?

编辑:当您想要在涉及重复时进行散列时,理想的数据结构是什么。我的意思是不应该忽略重复项并且应该插入。

4 个答案:

答案 0 :(得分:4)

不清楚你的散列问题是什么意思,"但也许你正在寻找multiset。来自Guava文档:

  

支持与顺序无关的相等性的集合,如Set,但可能包含重复的元素。 multiset有时也被称为包。

     

多个集合中彼此相等的元素称为相同单个元素的出现。多集中元素的出现次数称为该元素的计数(术语"频率"和"多样性"等效,但未在此API中使用)。 / p>

JDK中不存在这样的东西。

答案 1 :(得分:2)

  • 当您使用HashMap时,它会将原始值替换为新的副本。
  • 使用HashSet时,将忽略后续重复项(未插入)。
  • 当您使用ArrayList时,它只是将副本添加到列表的末尾

这完全取决于您的需求。

答案 2 :(得分:2)

如果您不想要重复,

ArrayList不是合乎逻辑的选择。针对不同用例的不同工具。

您可以在重复项无意义的区域使用Set,例如,一组学生。 List允许重复。

答案 3 :(得分:0)

如果您特别需要处理重复项的HashSetHashMap将能够完成这项工作。如果您只需要计算添加的对象数(使用快速查找/等),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;
    }
}

根据您的需要添加功能。