commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mischa Barthel" <>
Subject RE: [collections] testing equality with some Comparator
Date Wed, 23 Apr 2003 11:29:32 GMT
Hi Peter,

Thanks for your reaction. This:
> The best way to separate the 
> concerns of these
> two people is to create two Person classes for each access 
> level, and to use a
> tranformer function, so that each programmer can realize the 
> equals function
> he/she dreams about.
gave me the following idea. I will not use seperate Person classes but I
will use a transformer to give representatives of Persons. In general an
equivalence on any set also gives a partition of equivalence classes of
this set. These equivalence classes can be represented by a so called
equivalence class representative. I can use a Transformer to specify
these representatives. For my Person example:

public class PersonContentEquivClassRep implements Transformer {
  public Object transform(Object obj) {
    try {
      Person rep = (Person) BeanUtils.cloneBean(obj);


      return rep;
    } catch (Exception e) {
      return null;

  // singleton

So the method transform(Object obj) gives a representative for the
equivalence classes that I defined earlier with the PersonComparator.
Now I also implement Person.equals() and Person.hashCode() such that
Persons are equal iff all the members are equal:

  public int hashCode() {
    return (_id + name.hashCode() + address.hashCode());

  public boolean equals(Object obj) {
   if(!(obj instanceof Person)) {
      return false;
    } else {
      Person person = (Person) obj;
      return (person.getId() == this._id)
        && person.getName().equals(
        && person.getAddress().equals(this.address);

I have implemented PersonContentEquivClassRep in such a way that the
representative is unique with respect to Person.equals(). In general for
such Transformers the following must hold:
1 transform(Object obj) returns a representative of the equivalence
class of which obj is a member, where the alternative equivalence is
2 for each two Objects belonging to the same (alternative) equivalence
class transform(Object obj) returns a Object that is unique with respect
to the original equivalence (implemented in the equals method)
3 for each two Objects belonging to different (alternative) equivalence
classes transform(Object obj) returns Objects that are not equal with
respect to the original equivalence (implemented in the equals method)
Note: For these conditions to hold the origininal equivalence must be
stronger than the alternative. Example: If equals() just compared _ids
it would be impossible to implement PersonContentEquivClassRep such that
1-3  would hold, because an integer can not represent two Strings and
for each two combinations of Strings (name and address) a different
integer would be needed to satisfy 2 and 3.

Now I can solve my original problem using
CollectionUtils.collect(Collection, Transformer),
CollectionUtils.isEqualCollection(Collection, Collection) and my
Transformer. This is done as follows (from junit test case):

    Person person1 = new Person(1, "John", "Street");
    Person person2 = new Person(2, "Alice", "Another street");
    Person person3 = new Person(11, "John", "Street");
    Person person4 = new Person(12, "Alice", "Another street");
    Person person5 = new Person(13, "Bob", "Yet another street");

    Collection col1 = new ArrayList();
    Collection col2 = new ArrayList();


    PersonContentEquivClassRep personContentEquivClassRep =

    Collection col3 = CollectionUtils.collect(col1,
    Collection col4 = CollectionUtils.collect(col2,

    assertTrue(CollectionUtils.isEqualCollection(col3, col4));

CollectionUtils.isEqualCollection(col3, col4) now does what I originally
wanted: checking equivalence of collections wrt to an alternative
equivalence. This can easily be extended to other methods that use
equivalence. For example: contains:




View raw message