2

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

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

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

集合不过滤对象,它们仍然进入集合。有什么建议可以在不覆盖 equales 和 hashcode 函数的情况下创建集合列表?也许有番石榴或一些时髦的清单?谢谢,或者。

4

4 回答 4

12

在 Guava 中,有一个为此类事情设计的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来自动为你进行 wrap 和 unwrap Person

于 2012-09-20T08:46:17.790 回答
4

您可以使用自己的比较器创建TreeSet 。

Set<Person> set = new TreeSet<Person>(new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        // Your own compare logic
    }
});
于 2012-09-20T08:20:16.767 回答
4

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

于 2012-09-20T08:22:06.893 回答
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;
        }   

    }
}
于 2012-09-20T08:57:36.277 回答