Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Mechanism for having different equals (physical equals and logical equals) on objects in Collection

Is there any Equalator mechanism like Comparator so I can have different equals for coparing lists?

EDIT: My goal is to differentiate between current list1.equals(list2) which checks if its a shallow copy or also a deep copy with all objects a.equals(b) and list1.identical(list2) which checks if its simply shallow copy with unmodified listing

All these lists are from the same model. Some are copies of themselves so they hold the pointer to same objects, and others are deep copies so hierarchy is totally replicated, because they have updates in content, not just in structure.

I find myself oftenly makin list1.equals(list2) but I need a mechanism for telling if both are TOTAL copies (same objects in same order for collections) or sometimes if they are LOGICAL copies (through my own implemented logic equals), so list would call equals and objects should implement something more than a==b.

My problem is there is no Equalator interface, and if I override objects equals to I loose the capability of comparing by TOTAL EQUAL (a==b)

For example, this would be nice;

Collections.equal(l1,l2,new Equalator(){
    @Override public boolean equals(Obj1,Obj2){
          //Default lists comparison plus commparison of objects based on
          return (obj1.propertyX() == obj2.propertyX());
    }
});

and still I could do list1.equals(list2) so they use default equals (obj1==obj2) and this would be only true if contained objects are exactly the same.

First operation is useful for checking if list (which could be an updated list with totally recreated objects from the model) is still equals to the old list.

Second operation is useful for checking if list (which was a shallow copy of the old current version of data model), it does not contain any transcendent change from moving it around inside the code when it was the udpdated version.

EDIT: A very good example would be having a list of Point(x,y). We should be able to know if both list are equal because they are exactly same set of points or equal because the points they contain are equal in a logical way. If we could implement both phyEqual and logEqual to object, and have both methods in any object so list.phyEqual(list2) or list1.logEqual(list2)

like image 479
Whimusical Avatar asked Oct 08 '22 01:10

Whimusical


2 Answers

Your question doesn't really come across clearly, at least to me. If this doesn't answer it properly, could you re-word a little bit?

Within a given Collection concrete type, most equals implementations already do what you hint at. For instance:

    public boolean equals(Object o) {
        if (o == this)
            return true;

In this case, something like this might make sense.
You can easily override this:

    @Override
    public boolean equals(Object o) {
        if (o.getPrimaryKey() == this.getPrimaryKey()) 
            return true;
        return super().equals(o);

[test for nulls should be added] If you are creating standard collections, you can even anonymously override the equals method during construction.

If this doesn't do what you want, you could extend Collections yourself and override any of the methods there to do a similar thing.

Does that help?

like image 67
JoeG Avatar answered Oct 12 '22 22:10

JoeG


A late answer, but maybe it will be useful for someone...

The Guava Equivalence class is the same for equivalence as Comparator for comparing. You would need to write your own method for comparing the lists (there is no support in Guava for that), but then you could call this method with various equivalence-definitions.

Or you can roll your own interface:

interface Equalator<T> {
    boolean equals(T o1, T o2);
}

Again, you need to write your (trivial) method

boolean <T> listEquals(List<T> list1, List<T> list2, Equalator<T> equalator) {
    ...  
}

...but then you can reuse it with different ListEqualator implementations.

like image 24
lbalazscs Avatar answered Oct 13 '22 00:10

lbalazscs