Search code examples
javaequalsequalityindexof

Can I make indexOf compare objects in a different way?


I want to use indexOf but the objects in the List will not be equal objects but they would have value equality (ie. they're equivalent but not equal).

I want to make indexOf compare in a different way than the Object.equals method. I was thinking overridding the equals method to use my isEquivalent method instead but am unsure how to do this, if it is even possible.

I've tried many variations of this but keep getting errors:

List<CustomType> items{
        @Override
        public boolean equals(Object o)
        {
             return false;
        }
    }
    = //stuff to populate it

I've also seen this answer where they talk about EqualityComparer's is there something like that in java?

Or is there some other way to accomplish this?


Solution

  • Here is my crack at it. I used ArrayList because List is an interface and you would have needed to override all the methods.

    List<CustomType> customList = new ArrayList<CustomType>() {
        @Override
        public int indexOf(Object o) {
            if (o instanceof CustomType) {
                for (int i = 0; i < this.size(); i++) {
                    CustomType c = (CustomType) o;
                    if (c.isEquivalent(this.get(i))) {
                        return i;
                    }
                }
            }
            return -1;
        }
    };
    // use indexOf like normal, but beware of side-effects as mentioned in the comments
    

    Alternatively

    What I was trying to say in the comments earlier is that if you override List.equals, that implies you are comparing the List object with another object, not the objects within the list. To do what you are asking, you need to do it like this.

    class CustomType {
    
        public boolean isEquivalent(CustomType ct) {
            return true; // TODO: Implement this
        }
    
        @Override
        public boolean equals(Object obj) {
            // TODO: Implement this
            if (obj instanceof CustomType) {
                return this.isEquivalent((CustomType) obj); 
            }
            return false;
        }
    
        @Override
        public int hashCode() {
            return super.hashCode(); // TODO: Implement this
        }
    }
    
    public static void main(String args[]) {
        List<CustomType> lst = new ArrayList<CustomType>();
        // use indexOf like normal
    }