Java HashSet包含Object

时间:2014-12-01 21:56:31

标签: java object equals contains hashset

我使用重写的equals方法创建了自己的类,只检查名称(类中的属性)是否相等。现在我将该类的一些实例存储在HashSet中,以便HashSet中没有具有相同名称的实例。

我的问题:如何检查HashSet是否包含这样的对象。 .contains()在这种情况下不起作用,因为它适用于.equals()方法。我想检查它是否真的是同一个对象。

编辑:

package testprogram;

import java.util.HashSet;
import java.util.Set;

public class Example {
    private static final Set<Example> set = new HashSet<Example>();
    private final String name;
    private int example;

    public Example(String name, int example) {
        this.name = name;
        this.example = example;
        set.add(this);
    }

    public boolean isThisInList() {
        return set.contains(this);
        //will return true if this is just equal to any instance in the list
        //but it should not
        //it should return true if the object is really in the list
    }

    public boolean remove() {
        return set.remove(this);
    }

    //Override equals and hashCode
}

抱歉,我的英语技能不是很好。如果你不明白我的意思,请随时再问。

6 个答案:

答案 0 :(得分:2)

在您的情况下,判断对象的特定实例是否包含在HashSet中的唯一方法是迭代HashSet的内容,并比较对象标识(使用==运算符而不是equals( )方法)。

类似的东西:

boolean isObjectInSet(Object object, Set<? extends Object> set) {
   boolean result = false;

   for(Object o : set) {
     if(o == object) {
       result = true;
       break;
     }
   }

   return result;
}

答案 1 :(得分:2)

检查对象是否是同一个对象的方法是将它们与==进行比较,看看对象引用是否相等。

亲切的问候, 弗兰克

答案 2 :(得分:0)

您还必须覆盖hashCode方法。

答案 3 :(得分:0)

HashSet contains使用equals方法确定对象是否包含 - 并且重复项不会保留在HashSet中。

假设您的equalshashcode仅使用name字段......

HashSet<MyObject> objectSet = new HashSet<MyObject>();
MyObject name1Object = new MyObject("name1");

objectSet.add(new MyObject("name1"));
objectSet.add(name1Object);
objectSet.add(new MyObject("name2"));
//HashSet now contains 2 objects, name1Object and the new name2 object
//HashSets do not hold duplicate objects (name1Object and the new object with name1 would be considered duplicates)

objectSet.contains(new MyObject("name1")) // returns true
objectSet.contains(name1Object)           // returns true
objectSet.contains(new MyObject("name2")) // returns true
objectSet.contains(new MyObject("name3")) // returns false

如果您想检查HashSet中的对象是否是您要比较的确切对象,则必须将其拉出并使用==直接比较

for (MyObject o : objectSet)
{
    if (o == name1Object)
    {
        return true;
    }
}

如果对特定对象执行此操作,则可能更容易使用HashMap,因此您不必遍历列表以获取特定的命名对象。可能值得为你寻找,因为那时你可以这样做:

(objectMap.get("name") == myNameObject) // with a HashMap<String, MyNameObject> where "name" is the key string.

答案 4 :(得分:0)

试试这个.. 仅考虑一个属性&#39; name&#39;您的对象以保持唯一性。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (name == null ? 0 : name.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    User other = (User) obj;
    if (name == null) {
        if (other.name != null) {
            return false;
        }
    } else if (!name.equals(other.name)) {
        return false;
    }
    return true;
}

答案 5 :(得分:0)

  

我使用重写的equals方法创建了自己的类,只检查名称(类中的属性)是否相等。

这违反了.equals的合同,无论看起来多么方便,你都不能这样做。

相反,如果您想按某个属性(如名称)索引和查找元素,请使用HashMap<Name, YourType>来查找它们。或者,使用TreeSet并传递Comparator,仅比较名称。然后,您可以删除不正确的equals方法。

如果您想通过引用相等性找到对象,则有三种方法:

  1. 您的对象没有固有或有用的平等概念。

    不要实施equals。保持默认状态。然后,您可以使用HashSet查找引用相等性,使用HashMap或TreeSet按任何特定属性对其进行索引。

  2. 你的对象确实有一个有用的,普遍的平等概念,但你想要有效地找到等效的实例。

    几乎从来没有这种情况。但是,您可以使用例如一个Apache IdentityMap

  3. 你不关心效率。

    使用for循环和==每个元素。