Skip to content

Commit 5c76f7b

Browse files
committed
Add javaapi collection forwarders for 2.12 and 2.11
Adds 2.13 collection compatible forwarders for scala 2.11 and scala 2.12, see #346. 2.11 has converters in traits WrapAsJava and WrapAsScala, while 2.12 has them in AsJavaConverters and AsScalaConverters. The method names are the same, but unfortunately both CollectionConverters objects have to be separately defined for both sources, because of this import. Tests are added in a Java file, to verify that the methods can be called as java api.
1 parent a6d5f2f commit 5c76f7b

File tree

4 files changed

+282
-0
lines changed

4 files changed

+282
-0
lines changed
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)