diff --git a/core/shared/src/main/scala-2.12-/org/scalacheck/util/BuildableVersionSpecific.scala b/core/shared/src/main/scala-2.12-/org/scalacheck/util/BuildableVersionSpecific.scala index 43ffcb9a..5c98c45f 100644 --- a/core/shared/src/main/scala-2.12-/org/scalacheck/util/BuildableVersionSpecific.scala +++ b/core/shared/src/main/scala-2.12-/org/scalacheck/util/BuildableVersionSpecific.scala @@ -9,13 +9,19 @@ package org.scalacheck.util -import java.util.ArrayList +import java.util.{ArrayList, HashMap} import collection.{Map => _, _} import generic.CanBuildFrom import scala.collection.mutable.Builder private[util] trait BuildableVersionSpecific { + import scala.collection.JavaConverters._ + import scala.language.implicitConversions + + implicit def wrapArrayList[T](xs: ArrayList[T]): Traversable[T] = xs.asScala + implicit def wrapHashMap[K, V](xs: HashMap[K, V]): Traversable[(K, V)] = xs.asScala + implicit def buildableCanBuildFrom[T, F, C](implicit c: CanBuildFrom[F, T, C]): Buildable[T, C] = new Buildable[T, C] { def builder = c.apply @@ -32,6 +38,18 @@ private[util] class ArrayListBuilder[T] extends Builder[T, ArrayList[T]] { def result(): ArrayList[T] = al } +private[util] class HashMapBuilder[K, V] extends Builder[(K, V), HashMap[K, V]] { + private val hm = new HashMap[K, V] + + def +=(x: (K, V)): this.type = { + val (k, v) = x + hm.put(k, v) + this + } + def clear(): Unit = hm.clear() + def result(): HashMap[K, V] = hm +} + /** CanBuildFrom instances implementing Serializable, so that the objects capturing those can be serializable too. */ object SerializableCanBuildFroms { diff --git a/core/shared/src/main/scala-2.13+/org/scalacheck/util/BuildableVersionSpecific.scala b/core/shared/src/main/scala-2.13+/org/scalacheck/util/BuildableVersionSpecific.scala index 1e95b7e5..f36a33db 100644 --- a/core/shared/src/main/scala-2.13+/org/scalacheck/util/BuildableVersionSpecific.scala +++ b/core/shared/src/main/scala-2.13+/org/scalacheck/util/BuildableVersionSpecific.scala @@ -9,11 +9,16 @@ package org.scalacheck.util -import java.util.ArrayList +import java.util.{ArrayList, HashMap} import scala.collection.mutable.Builder -import scala.collection.{Map => _, _} +import scala.collection.{Map as _, *} private[util] trait BuildableVersionSpecific { + import scala.jdk.CollectionConverters._ + + implicit def wrapArrayList[T](xs: ArrayList[T]): Iterable[T] = xs.asScala + implicit def wrapHashMap[K, V](xs: HashMap[K, V]): Iterable[(K, V)] = xs.asScala + implicit def buildableFactory[T, C](implicit f: Factory[T, C]): Buildable[T, C] = new Buildable[T, C] { def builder = f.newBuilder @@ -30,6 +35,17 @@ private[util] class ArrayListBuilder[T] extends Builder[T, ArrayList[T]] { def result(): ArrayList[T] = al } +private[util] class HashMapBuilder[K, V] extends Builder[(K, V), HashMap[K, V]] { + private val hm = new HashMap[K, V] + def addOne(x: (K, V)): this.type = { + val (k, v) = x + hm.put(k, v) + this + } + def clear(): Unit = hm.clear() + def result(): HashMap[K, V] = hm +} + /** Factory instances implementing Serializable, so that the objects capturing those can be serializable too. */ // Named `...CanBuildFroms` for 2.12 source compatibility (`import SerializableCanBuildFroms._`) diff --git a/core/shared/src/main/scala/org/scalacheck/util/Buildable.scala b/core/shared/src/main/scala/org/scalacheck/util/Buildable.scala index e78b7ed7..fee467e7 100644 --- a/core/shared/src/main/scala/org/scalacheck/util/Buildable.scala +++ b/core/shared/src/main/scala/org/scalacheck/util/Buildable.scala @@ -22,12 +22,18 @@ trait Buildable[T, C] extends Serializable { } object Buildable extends BuildableVersionSpecific { - import java.util.ArrayList + import java.util.{ArrayList, HashMap} + implicit def buildableArrayList[T]: Buildable[T, ArrayList[T]] = new Buildable[T, ArrayList[T]] { def builder = new ArrayListBuilder[T] } + implicit def buildableHashMap[K, V]: Buildable[(K, V), HashMap[K, V]] = + new Buildable[(K, V), HashMap[K, V]] { + def builder = new HashMapBuilder[K, V] + } + def buildableSeq[T]: Buildable[T, Seq[T]] = new Buildable[T, Seq[T]] { def builder: mutable.Builder[T, Seq[T]] = diff --git a/core/shared/src/test/scala/org/scalacheck/util/BuildableSpecification.scala b/core/shared/src/test/scala/org/scalacheck/util/BuildableSpecification.scala index 98a599ff..19bfde44 100644 --- a/core/shared/src/test/scala/org/scalacheck/util/BuildableSpecification.scala +++ b/core/shared/src/test/scala/org/scalacheck/util/BuildableSpecification.scala @@ -12,6 +12,7 @@ package util import scala.collection._ +import Buildable._ import ScalaVersionSpecific._ object BuildableSpecification { @@ -47,4 +48,15 @@ object BuildableSpecification { implicit val iterableGen: Gen[immutable.Iterable[String]] = container[immutable.Iterable] implicit val trieIteratorGen: Gen[immutable.Queue[String]] = container[immutable.Queue] + + implicit val arrayListGen: Gen[java.util.ArrayList[String]] = container[java.util.ArrayList] + + def buildable[C[_, _]](implicit + evb: Buildable[(String, Long), C[String, Long]], + evt: C[String, Long] => Traversable[(String, Long)] + ) = Gen.buildableOf[C[String, Long], (String, Long)](for (str <- Gen.alphaStr; lng <- Gen.long) yield (str, lng)) + + implicit val mapGen: Gen[Map[String, Long]] = buildable[Map] + + implicit val hashMapGen: Gen[java.util.HashMap[String, Long]] = buildable[java.util.HashMap] }