Skip to content

Commit

Permalink
Merge pull request #9090 from NthPortal/topic/12059/PR
Browse files Browse the repository at this point in the history
[bug#12059] Make MapView#values return a View
  • Loading branch information
SethTisue committed Jul 2, 2020
2 parents f9738d3 + e15f471 commit dae21fe
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build.sbt
Expand Up @@ -394,6 +394,10 @@ val mimaFilterSettings = Seq {
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.convert.JavaCollectionWrappers$JPropertiesWrapper"),
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.convert.JavaCollectionWrappers$JSetWrapper"),
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.mutable.WeakHashMap"),

// Fix for scala/bug#12059
ProblemFilters.exclude[MissingClassProblem]("scala.collection.MapView$Keys"),
ProblemFilters.exclude[MissingClassProblem]("scala.collection.MapView$Values"),
),
}

Expand Down
30 changes: 30 additions & 0 deletions src/library/scala/collection/MapView.scala
Expand Up @@ -21,6 +21,20 @@ trait MapView[K, +V]

override def view: MapView[K, V] = this

// Ideally this returns a `View`, but bincompat
/** Creates a view over all keys of this map.
*
* @return the keys of this map as a view.
*/
override def keys: Iterable[K] = new MapView.Keys(this)

// Ideally this returns a `View`, but bincompat
/** Creates a view over all values of this map.
*
* @return the values of this map as a view.
*/
override def values: Iterable[V] = new MapView.Values(this)

/** Filters this map by retaining only keys satisfying a predicate.
* @param p the predicate used to test keys
* @return an immutable map consisting only of those key value pairs of this map where the key satisfies
Expand Down Expand Up @@ -82,6 +96,22 @@ object MapView extends MapViewFactory {
override def isEmpty: Boolean = underlying.isEmpty
}

// Ideally this is public, but bincompat
@SerialVersionUID(3L)
private class Keys[K](underlying: SomeMapOps[K, _]) extends AbstractView[K] {
def iterator: Iterator[K] = underlying.keysIterator
override def knownSize: Int = underlying.knownSize
override def isEmpty: Boolean = underlying.isEmpty
}

// Ideally this is public, but bincompat
@SerialVersionUID(3L)
private class Values[+V](underlying: SomeMapOps[_, V]) extends AbstractView[V] {
def iterator: Iterator[V] = underlying.valuesIterator
override def knownSize: Int = underlying.knownSize
override def isEmpty: Boolean = underlying.isEmpty
}

@SerialVersionUID(3L)
class MapValues[K, +V, +W](underlying: SomeMapOps[K, V], f: V => W) extends AbstractMapView[K, W] {
def iterator: Iterator[(K, W)] = underlying.iterator.map(kv => (kv._1, f(kv._2)))
Expand Down
32 changes: 32 additions & 0 deletions test/junit/scala/collection/MapViewTest.scala
Expand Up @@ -8,6 +8,7 @@ class MapViewTest {
def _toString(): Unit = {
assertEquals("MapView(<not computed>)", Map(1 -> 2).view.toString)
}

@deprecated("Tests deprecated API", since="2.13")
@Test
def testStringPrefixToString(): Unit = {
Expand All @@ -18,6 +19,7 @@ class MapViewTest {
}
assertEquals("FooMapView(<not computed>)", mapView.toString)
}

@Test
def testClassNameToString(): Unit = {
val mapView = new collection.MapView[Int,Int] {
Expand All @@ -27,4 +29,34 @@ class MapViewTest {
}
assertEquals("FooMapView(<not computed>)", mapView.toString)
}

@Test
def testKeysIsLazy(): Unit = {
var counter = 0
def assertLazy(): Unit = assertEquals(0, counter)

val map = (1 to 10).map(i => i -> i).toMap
val mapView = map.view.filterKeys(_ => { counter += 1; true })
assertLazy()
val keys = mapView.keys
assert(keys.isInstanceOf[View[_]])
assertLazy()
val _ = keys.map(_ + 1)
assertLazy()
}

@Test
def testValuesIsLazy(): Unit = {
var counter = 0
def assertLazy(): Unit = assertEquals(0, counter)

val map = (1 to 10).map(i => i -> i).toMap
val mapView = map.view.mapValues(i => { counter += 1; i })
assertLazy()
val values = mapView.values
assert(values.isInstanceOf[View[_]])
assertLazy()
val _ = values.map(_ + 1)
assertLazy()
}
}

0 comments on commit dae21fe

Please sign in to comment.