Decimals pretending to be Integers when used in Maps

This appears to be a defect, and I can tell you why. There are two functions that determine a key's behavior: equals and hashCode. The map implementation checks the results from equals and hashCode to see if a value is truly equal. Try the following:

System.assertEquals(System.hashCode(1234), System.hashCode(1234.0));

You'll find that you'll get an exception:

System.AssertException: Assertion Failed: Expected: 1234, Actual: 382541

As you can see, Decimal and Integer return separate hash code values for values that equals returns true for. This causes the system to get confused and create two entries (different keys) for what should be an equal value.

Do not attempt to mix classes when using keys (even primitives), or you'll get crazy results. This includes Id/String, Decimal/Integer/Double/Long, and any other apparently compatible values.

In the meantime, I think we should probably log a defect with salesforce.com, because this is strictly crazy.