Skip to content

Commit 15e8adf

Browse files
authored
Merge pull request #551 from DieBauer/collectionconverters-javaapi
2 parents 4629e6c + 39b57cf commit 15e8adf

File tree

5 files changed

+283
-1
lines changed

5 files changed

+283
-1
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ lazy val compat = new MultiScalaCrossProject(
8282
sharedSourceDir / "scala-2.11_2.12"
8383
}
8484
},
85-
versionPolicyIntention := Compatibility.BinaryAndSourceCompatible,
85+
versionPolicyIntention := Compatibility.BinaryCompatible,
8686
mimaBinaryIssueFilters ++= {
8787
import com.typesafe.tools.mima.core._
8888
import com.typesafe.tools.mima.core.ProblemFilters._
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.jdk.javaapi
14+
15+
import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
16+
import scala.collection.convert.{WrapAsJava, WrapAsScala}
17+
import scala.collection._
18+
19+
/** This object contains methods that convert between Scala and Java collections.
20+
*
21+
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
22+
* code, it is recommended to use the extension methods defined in
23+
* [[scala.jdk.CollectionConverters]].
24+
*/
25+
object CollectionConverters extends WrapAsJava with WrapAsScala {
26+
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)
27+
28+
def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)
29+
30+
def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)
31+
32+
def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)
33+
34+
def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)
35+
36+
def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)
37+
38+
def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)
39+
40+
def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)
41+
42+
def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)
43+
44+
def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)
45+
46+
def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)
47+
48+
def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)
49+
50+
def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)
51+
52+
def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)
53+
54+
def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)
55+
56+
def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)
57+
58+
def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)
59+
60+
def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)
61+
62+
def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)
63+
64+
def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
65+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.jdk.javaapi
14+
15+
import java.{lang => jl, util => ju}, java.util.{concurrent => juc}
16+
import scala.collection.convert.{AsJavaConverters, AsScalaConverters}
17+
import scala.collection._
18+
19+
/** This object contains methods that convert between Scala and Java collections.
20+
*
21+
* The explicit conversion methods defined here are intended to be used in Java code. For Scala
22+
* code, it is recommended to use the extension methods defined in
23+
* [[scala.jdk.CollectionConverters]].
24+
*/
25+
object CollectionConverters extends AsJavaConverters with AsScalaConverters {
26+
def asJava[A](i: Iterator[A]): ju.Iterator[A] = asJavaIterator(i)
27+
28+
def asJava[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)
29+
30+
def asJava[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)
31+
32+
def asJava[A](s: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(s)
33+
34+
def asJava[A](s: Seq[A]): ju.List[A] = seqAsJavaList(s)
35+
36+
def asJava[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)
37+
38+
def asJava[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)
39+
40+
def asJava[K, V](m: mutable.Map[K, V]): ju.Map[K, V] = mutableMapAsJavaMap(m)
41+
42+
def asJava[K, V](m: Map[K, V]): ju.Map[K, V] = mapAsJavaMap(m)
43+
44+
def asJava[K, V](m: concurrent.Map[K, V]): juc.ConcurrentMap[K, V] = mapAsJavaConcurrentMap(m)
45+
46+
def asScala[A](i: ju.Iterator[A]): Iterator[A] = asScalaIterator(i)
47+
48+
def asScala[A](e: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(e)
49+
50+
def asScala[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)
51+
52+
def asScala[A](c: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(c)
53+
54+
def asScala[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)
55+
56+
def asScala[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)
57+
58+
def asScala[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)
59+
60+
def asScala[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)
61+
62+
def asScala[A, B](d: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(d)
63+
64+
def asScala(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
65+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package test.scala.jdk.javaapi;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
import scala.Array;
6+
import scala.Tuple2;
7+
import scala.collection.Iterable;
8+
import scala.collection.Iterator;
9+
import scala.collection.concurrent.TrieMap;
10+
import scala.collection.mutable.*;
11+
import scala.collection.mutable.Map;
12+
import scala.collection.mutable.Set;
13+
import scala.jdk.javaapi.CollectionConverters;
14+
15+
import java.util.*;
16+
import java.util.concurrent.ConcurrentMap;
17+
18+
public class CollectionConvertersTest {
19+
20+
/**
21+
* The following conversions are supported via asScala and asJava:
22+
*
23+
* scala.collection.Iterable <=> java.lang.Iterable
24+
* scala.collection.Iterator <=> java.util.Iterator
25+
* scala.collection.mutable.Buffer <=> java.util.List
26+
* scala.collection.mutable.Set <=> java.util.Set
27+
* scala.collection.mutable.Map <=> java.util.Map
28+
* scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
29+
*/
30+
@Test
31+
public void shouldConvertAsScala() {
32+
// scala.collection.Iterable <=> java.lang.Iterable
33+
java.lang.Iterable iterable = CollectionConverters.asJava(TestObjects.iterable());
34+
Assert.assertEquals("A", iterable.iterator().next());
35+
Iterable scalaIterable = CollectionConverters.asScala(iterable);
36+
Assert.assertEquals(TestObjects.iterable().head(), scalaIterable.head());
37+
38+
// scala.collection.Iterator <=> java.util.Iterator
39+
java.util.Iterator iterator = CollectionConverters.asJava(TestObjects.iterator());
40+
Assert.assertEquals("A", iterator.next());
41+
Iterator scalaIterator = CollectionConverters.asScala(iterator);
42+
Assert.assertTrue(scalaIterator.contains("B"));
43+
44+
// scala.collection.mutable.Buffer <=> java.util.List
45+
List<String> list = CollectionConverters.asJava(TestObjects.buffer());
46+
Assert.assertEquals("A", list.get(0));
47+
Buffer<String> scalaBuffer = CollectionConverters.asScala(list);
48+
Assert.assertEquals("A", scalaBuffer.head());
49+
50+
// scala.collection.mutable.Set <=> java.util.Set
51+
java.util.Set<String> set = CollectionConverters.asJava(TestObjects.mutableSet());
52+
Assert.assertTrue(set.contains("A"));
53+
Set<String> scalaSet = CollectionConverters.asScala(set);
54+
Assert.assertTrue(scalaSet.contains("A"));
55+
56+
// scala.collection.mutable.Map <=> java.util.Map
57+
java.util.Map<String, String> map = CollectionConverters.asJava(TestObjects.mutableMap());
58+
Assert.assertEquals("B", map.get("A"));
59+
Map<String, String> scalaMap = CollectionConverters.asScala(map);
60+
Assert.assertEquals("B", scalaMap.get("A").get());
61+
62+
// scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
63+
ConcurrentMap<String, String> concurrentMap = CollectionConverters.asJava(TestObjects.concurrentMap());
64+
Assert.assertEquals("B", concurrentMap.get("A"));
65+
scala.collection.concurrent.Map<String, String> scalaConcurrentMap = CollectionConverters.asScala(concurrentMap);
66+
Assert.assertEquals("B", scalaConcurrentMap.get("A").get());
67+
}
68+
69+
/**
70+
* The following conversions are supported via asScala and through specially-named methods to convert to Java collections, as shown:
71+
*
72+
* scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
73+
* scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
74+
* scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
75+
*/
76+
public void convertAsCollection() {
77+
// scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
78+
Collection<String> collection = CollectionConverters.asJavaCollection(TestObjects.iterable());
79+
Assert.assertTrue(collection.contains("A"));
80+
Iterable<String> iterable = CollectionConverters.asScala(collection);
81+
Assert.assertEquals("A", iterable.head());
82+
83+
// scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
84+
Enumeration<String> enumeration = CollectionConverters.asJavaEnumeration(TestObjects.iterator());
85+
Assert.assertEquals("A", enumeration.nextElement());
86+
Iterator<String> iterator = CollectionConverters.asScala(enumeration);
87+
Assert.assertEquals("A", iterator.next());
88+
89+
// scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
90+
Dictionary<String, String> dictionary = CollectionConverters.asJavaDictionary(TestObjects.mutableMap());
91+
Assert.assertEquals("B", dictionary.get("A"));
92+
Map<String, String> map = CollectionConverters.asScala(dictionary);
93+
Assert.assertEquals("B", map.get("A").get());
94+
}
95+
96+
/** In addition, the following one-way conversions are provided via asJava:
97+
*
98+
* scala.collection.Seq => java.util.List
99+
* scala.collection.mutable.Seq => java.util.List
100+
* scala.collection.Set => java.util.Set
101+
* scala.collection.Map => java.util.Map
102+
*/
103+
public void convertsAsJava() {
104+
// scala.collection.Seq => java.util.List
105+
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.seq()).get(0));
106+
107+
// scala.collection.mutable.Seq => java.util.List
108+
Assert.assertEquals("A", CollectionConverters.asJava(TestObjects.mutableSeq()).get(0));
109+
110+
// scala.collection.Set => java.util.Set
111+
Assert.assertTrue(CollectionConverters.asJava(TestObjects.set()).contains("A"));
112+
113+
// scala.collection.Map => java.util.Map
114+
Assert.assertEquals("B", CollectionConverters.asJava(TestObjects.map()).get("A"));
115+
}
116+
117+
/**
118+
* The following one way conversion is provided via asScala:
119+
*
120+
* java.util.Properties => scala.collection.mutable.Map
121+
*/
122+
public void convertsFromProperties() {
123+
Properties properties = new Properties();
124+
properties.put("key", "value");
125+
Map<String, String> stringStringMap = CollectionConverters.asScala(properties);
126+
Assert.assertEquals("value", stringStringMap.get("key").get());
127+
}
128+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package test.scala.jdk.javaapi
2+
3+
import scala.collection.concurrent.TrieMap
4+
import scala.collection.mutable
5+
import scala.collection.mutable.ArrayBuffer
6+
import scala.collection.mutable.Buffer
7+
8+
/**
9+
* Scala collection objects defined for easy access in a Java class
10+
*/
11+
object TestObjects {
12+
13+
val seq: scala.collection.Seq[String] = ArrayBuffer("A", "B")
14+
val mutableSeq: scala.collection.mutable.Seq[String] = ArrayBuffer("A", "B")
15+
val set: scala.collection.Set[String] = Set("A", "B")
16+
val map: scala.collection.Map[String, String] = Map("A" -> "B")
17+
18+
val iterable: scala.collection.Iterable[String] = Iterable("A", "B")
19+
val iterator: scala.collection.Iterator[String] = Iterator("A", "B")
20+
val buffer: scala.collection.mutable.Buffer[String] = mutable.Buffer("A", "B")
21+
val mutableSet: scala.collection.mutable.Set[String] = mutable.Set("A", "B")
22+
val mutableMap: scala.collection.mutable.Map[String, String] = mutable.Map("A" -> "B")
23+
val concurrentMap: scala.collection.concurrent.Map[String, String] = TrieMap("A" -> "B")
24+
}

0 commit comments

Comments
 (0)