Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Make MapWrapper.Entry's hashCode conform to the contract in java.util.Map.Entry's documentation #487

Merged
merged 1 commit into from
Mar 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,16 @@ private[collection] trait Wrappers {
def getKey = k
def getValue = v
def setValue(v1 : B) = self.put(k, v1)
override def hashCode = byteswap32(k.##) + (byteswap32(v.##) << 16)

// It's important that this implementation conform to the contract
// specified in the javadocs of java.util.Map.Entry.hashCode
//
// See https://github.com/scala/bug/issues/10663
override def hashCode = {
(if (k == null) 0 else k.hashCode()) ^
(if (v == null) 0 else v.hashCode())
}

override def equals(other: Any) = other match {
case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue
case _ => false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.util

@RunWith(classOf[JUnit4])
class MapWrapperTest {
Expand Down Expand Up @@ -49,11 +50,33 @@ class MapWrapperTest {

// test for scala/bug#8504
@Test
def testHashCode(): Unit = {
def testHashCodeNulls(): Unit = {
import strawman.collection.JavaConverters._
val javaMap = strawman.collection.immutable.Map(1 -> null).asJava

// Before the fix for scala/bug#8504, this throws a NPE
javaMap.hashCode
}

// regression test for https://github.com/scala/bug/issues/10663
@Test
def testHashCodeEqualsMatchesJavaMap() {
import strawman.collection.JavaConverters._

val jmap = new util.HashMap[String, String]()
jmap.put("scala", "rocks")
jmap.put("java interop is fun!", "ya!")
jmap.put("Ĺởồҝ ïŧ\\'ş ūŋǐčōđẹ", "whyyyy")
jmap.put("nulls nooo", null)
jmap.put(null, "null keys are you serious??")

// manually convert to scala map
val scalaMap = jmap.entrySet().iterator().asScala.map { e => e.getKey -> e.getValue}.toMap

val mapWrapper = scalaMap.asJava

assertEquals(jmap.hashCode(), mapWrapper.hashCode())
assertTrue(jmap == mapWrapper)
assertTrue(mapWrapper == jmap)
}
}