如何用具有唯一字段的对象填充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;
}
}
答案 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的提交者。