一个HashSet.contains()返回一个Object

时间:2015-04-02 01:59:38

标签: java performance collections hashset asymptotic-complexity

假设我正在收藏中使用A类型。

class A {
    ThisType thisField; 
    ThatType thatField; 
    String otherField; 
}

只有thisFieldthatField才能识别A的实例 - 因此会覆盖其equals()及其hashCode()方法。 这样,在HashSet<A> setOfAs中,A的对象在其thisFieldthatField)值对中是唯一的。

在应用程序的某个位置,我需要查找Set的{​​{1}}实例,如果存在,请打印其A - 元信息。

我可以

i。)在otherField上获取一个迭代器,查看每个条目的setOfAsthisField值,如果它们都匹配,则打印其thatField

ii。)使用自我映射otherField,其中键和值是每个条目中的相同对象。使用(HashMap<A,A> selfMapAA)值对实例化thisField以查找thatField并获取其匹配的条目(如果它在那里)。

(i)是selfMapA - 虽然它在恒定时间内找到它,但它不会在恒定时间内得到它。

(ii)在恒定时间内获取对象,这是我们在系统中使用的内容。然而,它使用了两倍的内存。

我正在寻找的是一个设置结构,它获取它在恒定时间内找到的对象条目。例如,一个带有 O(n)方法返回contains(Object),它找到的对象(如果存在,而不是Objectboolean

有更好的替代方案吗?有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

HashSet是使用HashMap实现的,所有值都设置为虚拟对象,因此选项2实际上应该使用比HashSet略少的内存。我会选择2。

答案 1 :(得分:0)

正如User235 ...所说,HashSet是使用HashMap实现的,因此两者之间的内存使用差异可以忽略不计。这有恒定的时间添加和查找,所以时间复杂性你不能做得更好。因此,考虑到这一点,使用hashmap可能是最好的答案。

public class Database<A>{
    private HashMap<A,A> db = new HashMap<A,A>();

    /** Adds a to this database. If there was already a in this database,
     * overwrites the old a - updates the metaData 
     */
    public void add(A a){
        db.put(a,a);
    }

    /** Removes a from this database, if present */
    public void remove(A a){
        db.remove(a);
    }

    /** Returns the metadata associated with a in this database.
     * As instances of A hash on thisField and thatField, this
     * may be a different string than a.otherField.
     * Returns null if a is not present in this database.
     */
    public String getMetaData(A a){
        A dat = db.get(a);
        return dat != null ? dat.otherField : null;
    }
}