Skip to content

Commit

Permalink
Merge pull request #551 from DieBauer/collectionconverters-javaapi
Browse files Browse the repository at this point in the history
  • Loading branch information
SethTisue authored Aug 26, 2022
2 parents 4629e6c + 39b57cf commit 15e8adf
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 1 deletion.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ lazy val compat = new MultiScalaCrossProject(
sharedSourceDir / "scala-2.11_2.12"
}
},
versionPolicyIntention := Compatibility.BinaryAndSourceCompatible,
versionPolicyIntention := Compatibility.BinaryCompatible,
mimaBinaryIssueFilters ++= {
import com.typesafe.tools.mima.core._
import com.typesafe.tools.mima.core.ProblemFilters._
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk.javaapi

import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
import scala.collection.convert.{WrapAsJava, WrapAsScala}
import scala.collection._

/** This object contains methods that convert between Scala and Java collections.
*
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
* code, it is recommended to use the extension methods defined in
* [[scala.jdk.CollectionConverters]].
*/
object CollectionConverters extends WrapAsJava with WrapAsScala {
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)

def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)

def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)

def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)

def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)

def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)

def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)

def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)

def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)

def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)

def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)

def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)

def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)

def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)

def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)

def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)

def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)

def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)

def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)

def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.jdk.javaapi

import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
import scala.collection.convert.{AsJavaConverters, AsScalaConverters}
import scala.collection._

/** This object contains methods that convert between Scala and Java collections.
*
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
* code, it is recommended to use the extension methods defined in
* [[scala.jdk.CollectionConverters]].
*/
object CollectionConverters extends AsJavaConverters with AsScalaConverters {
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)

def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)

def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)

def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)

def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)

def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)

def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)

def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)

def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)

def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)

def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)

def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)

def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)

def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)

def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)

def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)

def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)

def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)

def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)

def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package test.scala.jdk.javaapi;

import org.junit.Assert;
import org.junit.Test;
import scala.Array;
import scala.Tuple2;
import scala.collection.Iterable;
import scala.collection.Iterator;
import scala.collection.concurrent.TrieMap;
import scala.collection.mutable.*;
import scala.collection.mutable.Map;
import scala.collection.mutable.Set;
import scala.jdk.javaapi.CollectionConverters;

import java.util.*;
import java.util.concurrent.ConcurrentMap;

public class CollectionConvertersTest {

/**
* The following conversions are supported via asScala and asJava:
*
* scala.collection.Iterable <=> java.lang.Iterable
* scala.collection.Iterator <=> java.util.Iterator
* scala.collection.mutable.Buffer <=> java.util.List
* scala.collection.mutable.Set <=> java.util.Set
* scala.collection.mutable.Map <=> java.util.Map
* scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
*/
@Test
public void shouldConvertAsScala() {
// scala.collection.Iterable <=> java.lang.Iterable
java.lang.Iterable iterable = CollectionConverters.asJava(TestObjects.iterable());
Assert.assertEquals("A", iterable.iterator().next());
Iterable scalaIterable = CollectionConverters.asScala(iterable);
Assert.assertEquals(TestObjects.iterable().head(), scalaIterable.head());

// scala.collection.Iterator <=> java.util.Iterator
java.util.Iterator iterator = CollectionConverters.asJava(TestObjects.iterator());
Assert.assertEquals("A", iterator.next());
Iterator scalaIterator = CollectionConverters.asScala(iterator);
Assert.assertTrue(scalaIterator.contains("B"));

// scala.collection.mutable.Buffer <=> java.util.List
List<String> list = CollectionConverters.asJava(TestObjects.buffer());
Assert.assertEquals("A", list.get(0));
Buffer<String> scalaBuffer = CollectionConverters.asScala(list);
Assert.assertEquals("A", scalaBuffer.head());

// scala.collection.mutable.Set <=> java.util.Set
java.util.Set<String> set = CollectionConverters.asJava(TestObjects.mutableSet());
Assert.assertTrue(set.contains("A"));
Set<String> scalaSet = CollectionConverters.asScala(set);
Assert.assertTrue(scalaSet.contains("A"));

// scala.collection.mutable.Map <=> java.util.Map
java.util.Map<String, String> map = CollectionConverters.asJava(TestObjects.mutableMap());
Assert.assertEquals("B", map.get("A"));
Map<String, String> scalaMap = CollectionConverters.asScala(map);
Assert.assertEquals("B", scalaMap.get("A").get());

// scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
ConcurrentMap<String, String> concurrentMap = CollectionConverters.asJava(TestObjects.concurrentMap());
Assert.assertEquals("B", concurrentMap.get("A"));
scala.collection.concurrent.Map<String, String> scalaConcurrentMap = CollectionConverters.asScala(concurrentMap);
Assert.assertEquals("B", scalaConcurrentMap.get("A").get());
}

/**
* The following conversions are supported via asScala and through specially-named methods to convert to Java collections, as shown:
*
* scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
* scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
* scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
*/
public void convertAsCollection() {
// scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
Collection<String> collection = CollectionConverters.asJavaCollection(TestObjects.iterable());
Assert.assertTrue(collection.contains("A"));
Iterable<String> iterable = CollectionConverters.asScala(collection);
Assert.assertEquals("A", iterable.head());

// scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
Enumeration<String> enumeration = CollectionConverters.asJavaEnumeration(TestObjects.iterator());
Assert.assertEquals("A", enumeration.nextElement());
Iterator<String> iterator = CollectionConverters.asScala(enumeration);
Assert.assertEquals("A", iterator.next());

// scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
Dictionary<String, String> dictionary = CollectionConverters.asJavaDictionary(TestObjects.mutableMap());
Assert.assertEquals("B", dictionary.get("A"));
Map<String, String> map = CollectionConverters.asScala(dictionary);
Assert.assertEquals("B", map.get("A").get());
}

/** In addition, the following one-way conversions are provided via asJava:
*
* scala.collection.Seq => java.util.List
* scala.collection.mutable.Seq => java.util.List
* scala.collection.Set => java.util.Set
* scala.collection.Map => java.util.Map
*/
public void convertsAsJava() {
// scala.collection.Seq => java.util.List
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.seq()).get(0));

// scala.collection.mutable.Seq => java.util.List
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.mutableSeq()).get(0));

// scala.collection.Set => java.util.Set
Assert.assertTrue(CollectionConverters.asJava(TestObjects.set()).contains("A"));

// scala.collection.Map => java.util.Map
Assert.assertEquals("B", CollectionConverters.asJava(TestObjects.map()).get("A"));
}

/**
* The following one way conversion is provided via asScala:
*
* java.util.Properties => scala.collection.mutable.Map
*/
public void convertsFromProperties() {
Properties properties = new Properties();
properties.put("key", "value");
Map<String, String> stringStringMap = CollectionConverters.asScala(properties);
Assert.assertEquals("value", stringStringMap.get("key").get());
}
}
24 changes: 24 additions & 0 deletions compat/src/test/scala-jvm/test/scala/jdk/javaapi/TestObjects.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package test.scala.jdk.javaapi

import scala.collection.concurrent.TrieMap
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer

/**
* Scala collection objects defined for easy access in a Java class
*/
object TestObjects {

val seq: scala.collection.Seq[String] = ArrayBuffer("A", "B")
val mutableSeq: scala.collection.mutable.Seq[String] = ArrayBuffer("A", "B")
val set: scala.collection.Set[String] = Set("A", "B")
val map: scala.collection.Map[String, String] = Map("A" -> "B")

val iterable: scala.collection.Iterable[String] = Iterable("A", "B")
val iterator: scala.collection.Iterator[String] = Iterator("A", "B")
val buffer: scala.collection.mutable.Buffer[String] = mutable.Buffer("A", "B")
val mutableSet: scala.collection.mutable.Set[String] = mutable.Set("A", "B")
val mutableMap: scala.collection.mutable.Map[String, String] = mutable.Map("A" -> "B")
val concurrentMap: scala.collection.concurrent.Map[String, String] = TrieMap("A" -> "B")
}

0 comments on commit 15e8adf

Please sign in to comment.