如何添加具有唯一字段的对象到Set

时间:2016-07-02 20:24:17

标签: java set

如何用具有唯一字段的对象填充Set?

例如,我有一个类Person,它有一个名为name的唯一字段,因此如果我添加设置一个具有重复名称的对象,则不应添加该字段。

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Set<Person> objList = new HashSet<Person>();
        objList.add(new Person("John", "New York", "Accountant"));
        objList.add(new Person("Bill", "London", "Manager"));
        objList.add(new Person("John", "New York", "Driver"));// this object should not be added

        for(Person o : objList){
            System.out.println(o.name);//here should printed only John and Bill
        }
    }
}

class Person {
    String name;//must be unique
    String city;
    String position;

    public Person(String c_name, String c_city, String c_position){
        this.name = c_name;
        this.city = c_city;
        this.position = c_position;
    }
}

3 个答案:

答案 0 :(得分:2)

换句话说,你的意思是这个人的名字定义了它的身份。您可以通过覆盖equals(Object)hashCode方法来仅包含它来产生此类行为:

public class Person {
    // members, constructors, etc.

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Person)) {
            return false;
        }
        return name.equals(((Person)other).name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

答案 1 :(得分:1)

您需要覆盖Person类中Object类的equals()和hashcode()方法才能实现此目的。 由于您没有为HashSet执行此操作,因此Person类的所有对象都不同,并且hashSet将允许您添加所有Person。

以下是Person类的代码片段,仅用于唯一名称。

class Person{
    String name;//must be unique
    String city;
    String position;

    public Person(String c_name, String c_city, String c_position){
        this.name = c_name;
        this.city = c_city;
        this.position = c_position;
    }

    @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;
        Person other = (Person) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

答案 2 :(得分:1)

您可以使用UnifiedSetWithHashingStrategy中的Eclipse Collections为您的Set定义自己的自定义哈希策略。以下代码适用于您的示例。

HashingStrategy<Person> uniqueNameStrategy = new HashingStrategy<Person>() {
    @Override
    public int computeHashCode(Person person) {
        return person.name.hashCode();
    }

    @Override
    public boolean equals(Person person1, Person person2) {
        return person1.name.equals(person2.name);
    }
};

UnifiedSetWithHashingStrategy<Person> people = 
    UnifiedSetWithHashingStrategy.newSet(uniqueNameStrategy);

people.add(new Person("John", "New York", "Accountant"));
people.add(new Person("Bill", "London", "Manager"));
people.add(new Person("John", "New York", "Driver"));

people.each(person -> System.out.println(person.name + "/" + person.position));
//    Bill/Manager
//    John/Accountant

注意:我是Eclipse Collections的提交者。