jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • groovy
  • GROOVY-626

GString hash codes are incorretly calculated

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Won't Fix
  • Affects Version/s: 1.0-beta-6
  • Fix Version/s: None
  • Component/s: groovy-jdk
  • Labels:
    None

Description

println "${2}".hashCode() == "2".hashCode()

prints

false

println "${2}" == "2"

prints true

The hashCodes should be identical.

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Edwin Tellman added a comment - 25/Oct/06 4:31 AM

I reproduced this issue with the test case below and found a little more information. The equals() and hashCode() methods seem to be consistent with each other but inconsistent with ==. This is probably because "2" is a java.lang.String and "${2}" is a groovy.lang.GString.

void testEqualsTemplateToLiteral() {
def template = "${2}"
def literal = "2"

// prints "class java.lang.String"
print("literal: ${literal.getClass()}\n")

// prints "class GStringTest$67"
print("template: ${template.getClass()}\n")

// succeeds
assertTrue("template == literal not true", template == literal)

// these all fail
assertTrue("literal not equal to template", literal.equals(template))
assertTrue("template not equal to literal", template.equals(literal))
assertEquals("hash codes not equal", literal.hashCode(), template.hashCode())
}

Show
Edwin Tellman added a comment - 25/Oct/06 4:31 AM I reproduced this issue with the test case below and found a little more information. The equals() and hashCode() methods seem to be consistent with each other but inconsistent with ==. This is probably because "2" is a java.lang.String and "${2}" is a groovy.lang.GString. void testEqualsTemplateToLiteral() { def template = "${2}" def literal = "2" // prints "class java.lang.String" print("literal: ${literal.getClass()}\n") // prints "class GStringTest$67" print("template: ${template.getClass()}\n") // succeeds assertTrue("template == literal not true", template == literal) // these all fail assertTrue("literal not equal to template", literal.equals(template)) assertTrue("template not equal to literal", template.equals(literal)) assertEquals("hash codes not equal", literal.hashCode(), template.hashCode()) }
Hide
Permalink
Guillaume Laforge added a comment - 02/Nov/07 6:26 AM

If it's still a problem, please reopen.

Show
Guillaume Laforge added a comment - 02/Nov/07 6:26 AM If it's still a problem, please reopen.
Hide
Permalink
blackdrag blackdrag added a comment - 02/Nov/07 7:55 AM

GString and Strings do not have the same hashcode by design.

Show
blackdrag blackdrag added a comment - 02/Nov/07 7:55 AM GString and Strings do not have the same hashcode by design.
Hide
Permalink
Alexander Veit added a comment - 08/Aug/08 5:28 PM

As Edwin said equals and hashCode are consistent, but

assert "${2}".hashCode() != "2".hashCode() // good
assert "${2}".equals("2") == false // good
assert "${2}" == "2" // bad
assert "2" == "${2}" // bad

surprisingly fails.

The problem is
DefaultTypeTransformation#compareEqual(Object, Object)
which dispatches to
DefaultTypeTransformation#compareToWithEqualityCheck(Object, Object, boolean)
which makes use of the object's Comparable semantics. This is inadequate (and also inefficient) since inequality could be easily proven by GString's equals method.

Show
Alexander Veit added a comment - 08/Aug/08 5:28 PM As Edwin said equals and hashCode are consistent, but assert "${2}".hashCode() != "2".hashCode() // good assert "${2}".equals("2") == false // good assert "${2}" == "2" // bad assert "2" == "${2}" // bad surprisingly fails. The problem is DefaultTypeTransformation#compareEqual(Object, Object) which dispatches to DefaultTypeTransformation#compareToWithEqualityCheck(Object, Object, boolean) which makes use of the object's Comparable semantics. This is inadequate (and also inefficient) since inequality could be easily proven by GString's equals method.

People

  • Assignee:
    Guillaume Laforge
    Reporter:
    John Wilson
Vote (1)
Watch (1)

Dates

  • Created:
    31/Aug/04 12:31 PM
    Updated:
    08/Aug/08 5:28 PM
    Resolved:
    02/Nov/07 6:26 AM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.