[ 
https://issues.apache.org/jira/browse/GROOVY-6151?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17476879#comment-17476879
 ] 

Eric Milles commented on GROOVY-6151:
-------------------------------------

Here is a possible solution, although it gets tripped up by MapWithDefault 
which provides an equals:
{code:java}
    /**
     * Compares two Maps treating coerced numerical values as identical.
     * <p>
     * Example usage:
     * <pre class="groovyTestCase">
     * assert [a:2, b:3] == [a:2L, b:3.0]
     *
     * class Groovy6151 extends HashMap {
     *     String item
     *     boolean equals(Object that) {
     *         that instanceof Groovy6151 && that.@item == this.@item && 
super.equals(that)
     *     }
     * }
     * def one = new Groovy6151(item:'x')
     * assert one == one
     * def two = new Groovy6151(item:'y')
     * assert one != two
     * </pre>
     *
     * @param self  this Map
     * @param other the Map being compared to
     * @return <tt>true</tt> if the contents of both maps are identical
     * @since 1.8.0
     */
    public static boolean equals(Map self, Map other) {
        if (self == other) {
            return true;
        }
        if (null == other) {
            return false;
        }

        // GROOVY-6151: check for explicit declaration of equals
        Method[] methods = self.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().equals("equals") && method.getParameterCount() 
== 1
                    && 
method.getParameterTypes()[0].isAssignableFrom(other.getClass())) {
                try {
                    return (Boolean) method.invoke(self, other);
                } catch (ReflectiveOperationException e) {
                    throw new GroovyRuntimeException(e);
                }
            }
        }

        if (self.size() != other.size()) {
            return false;
        }
        if (!self.keySet().equals(other.keySet())) {
            return false;
        }
        for (Object o : self.entrySet()) {
            Map.Entry entry = (Map.Entry) o;
            Object key = entry.getKey();
            Object value = entry.getValue();
            if (!coercedEquals(value, other.get(key))) {
                return false;
            }
        }
        return true;
    }
{code}

> Equal on class (extends Map)
> ----------------------------
>
>                 Key: GROOVY-6151
>                 URL: https://issues.apache.org/jira/browse/GROOVY-6151
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 2.1.3
>            Reporter: Grzegorz Karawacki
>            Priority: Major
>         Attachments: Main.groovy, TestError.groovy
>
>
> The problem occurs for classes inherit from class Map:
> {code:title=TestError.groovy|borderStyle=solid}
> class TestError extends HashMap {
>     String id
>     String getId() {
>         return id
>     }
>     void setId(String id) {
>         this.id = id
>     }
>     boolean equals(Object o) {
>         if (this.is(o)) return true
>         if (getClass() != o.class) return false
>         if (!super.equals(o)) return false
>         TestError testError = (TestError) o
>         if (id != testError.id) return false
>         return true
>     }
>     int hashCode() {
>         int result = super.hashCode()
>         result = 31 * result + (id != null ? id.hashCode() : 0)
>         return result
>     }
> }
> {code}
> {code:title=Main.groovy|borderStyle=solid}
> TestError t1 = new TestError()
> t1.setId("1")
> TestError t2 = new TestError()
> t2.setId("2")
> println(t1.getId())
> println(t2.getId())
> println(t1.equals(t2))
> {code}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to