2

提案を探しています。Person次のような同じ文字列でリスト値を挿入しようとしているときに、StringfirstNameとStringlastNameを持つクラスがあります。

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

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

セットはオブジェクトをフィルタリングせず、オブジェクトは引き続きセットに含まれます。イコールとハッシュコード関数をオーバーライドせずにセットリストを作成するための提案はありますか?たぶんグアバやいくつかのグルーヴィーなリストで?ありがとう、または。

4

4 に答える 4

12

グアバには、そのようなことを目的として設計された同値類があります。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を作成して、sを自動的にラップおよびアンラップすることができ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。を使用しないか、内部を実装してそれに基づく別のクラスでSetラップします(Guavaでこれを行う方法については、他の回答を参照してください)。PersonequalshashcodePerson

于 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 に答える