我正在寻找建议。
我有一个Person
类,其中包含String firstName和String lastName
当我想要使用相同的字符串插入列表值时:
set.add(new Person("firstName","lastName"))
set.add(new Person("firstName","lastName"))
该集合不会过滤对象,但它们仍会进入集合。 有没有建议创建集合列表而不重写equales和hashcode函数? 也许用番石榴或一些groovy列表? 谢谢, 或
答案 0 :(得分:11)
在番石榴中有一个Equivalence课程,专门针对这些事情。像这样创建自己的Equivalence
类:
import com.google.common.base.Equivalence;
import com.google.common.base.Objects;
public class PersonEquivalence extends Equivalence<Person> {
@Override
protected boolean doEquivalent(Person p1, Person p2) {
return Objects.equal(p1.getFistName(), p2.getFistName())
&& Objects.equal(p1.getLastName(), p2.getLastName());
}
@Override
protected int doHash(Person person) {
return Objects.hashCode(person.getFistName(), person.getLastName());
}
}
然后是这段代码
Set<Equivalence.Wrapper<Person>> set = Sets.newHashSet();
PersonEquivalence personEquivalence = new PersonEquivalence();
set.add(personEquivalence.wrap(new Person("Joe", "Doe")));
set.add(personEquivalence.wrap(new Person("Joe", "Doe")));
set.add(personEquivalence.wrap(new Person("Jane", "Doe")));
System.out.println(set);
打印
[PersonEquivalence@8813f2.wrap(Person{firstName=Jane, lastName=Doe}),
PersonEquivalence@8813f2.wrap(Person{firstName=Joe, lastName=Doe})]
当然它有点冗长,但你可以创建ForwardingSet来自动包装和解包Person
。
答案 1 :(得分:4)
您可以使用自己的比较器创建TreeSet。
Set<Person> set = new TreeSet<Person>(new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
// Your own compare logic
}
});
答案 2 :(得分:4)
你不能违反Set
的合同。要么不使用Set
,要么将Person
包装在另一个根据内部equals
实现hashcode
和Person
的类中(请参阅其他答案)为了在番石榴中做到这一点。
答案 3 :(得分:0)
这是对我的地图建议的粗略尝试。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class PeopleCarrier implements Iterable<Person>{
private Map<PersonKey, Person> storage = new HashMap<PersonKey, Person>();
public void add(Person p) {
PersonKey pk = new PersonKey(p);
storage.put(pk, p);
}
public boolean contains(Person p) {
return storage.containsKey(new PersonKey(p));
}
@Override
public Iterator<Person> iterator() {
return new Iterator<Person>() {
private Iterator<PersonKey> i = storage.keySet().iterator();
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Person next() {
return storage.get(i.next());
}
@Override
public boolean hasNext() {
return i.hasNext();
}
};
}
private class PersonKey {
private String firstname;
private String lastname;
public PersonKey(Person p) {
this.firstname = p.getFirstname();
this.lastname = p.getLastname();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result
+ ((firstname == null) ? 0 : firstname.hashCode());
result = prime * result
+ ((lastname == null) ? 0 : lastname.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof PersonKey))
return false;
PersonKey other = (PersonKey) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (firstname == null) {
if (other.firstname != null)
return false;
} else if (!firstname.equals(other.firstname))
return false;
if (lastname == null) {
if (other.lastname != null)
return false;
} else if (!lastname.equals(other.lastname))
return false;
return true;
}
private PeopleCarrier getOuterType() {
return PeopleCarrier.this;
}
}
}