如何在不改变equals和hashcode的情况下插入到set中

我正在寻找一个建议。 我有一个带有firstName和String lastName的Person类当我想要插入具有相同String的列表值时:

 set.add(new Person("firstName","lastName")) set.add(new Person("firstName","lastName")) 

该集合不会过滤对象,他们仍然进入集合。 有没有建议创建集合列表而不覆盖equales和hashcode函数? 也许用番石榴或一些groovy列表? 谢谢,或者。

您可以使用自己的Comparator创建TreeSet 。

 Set set = new TreeSet(new Comparator() { @Override public int compare(Person p1, Person p2) { // Your own compare logic } }); 

在番石榴中有一个等价类,专门用于此类事物。 像这样创建自己的Equivalence类:

 import com.google.common.base.Equivalence; import com.google.common.base.Objects; public class PersonEquivalence extends Equivalence { @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> 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

你不能违反Set的合同。 要么不使用Set ,要么将Person包装在另一个实现基于内部Person equalshashcode类中(有关在Guava中执行此操作的方法,请参阅另一个答案)。

这是对我的地图建议的粗略尝试。

 import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class PeopleCarrier implements Iterable{ private Map storage = new HashMap(); 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 iterator() { return new Iterator() { private Iterator 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; } } }