- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Scala collection classes implementing java.util.* interfaces
Fri, 2009-04-10, 08:22
We've written a few middle-tier apps in Scala now and we're using ZeroC's Ice
for the RPC layer. In Ice we write something like this in a Slice language and
then run slice2java to generate Java abstract classes, which we extend to
implement the API.
module MyApp
{
["java:type:java.util.HashMap"]
dictionary AttributeMap;
interface FooBar
{
AttributeMap getAttributes();
};
};
The Ice runtime code that unserializes the wire protocol expects a java.util.*
collection interface to insert into. So if we have something that wrapped a
scala.collection.mutable.HashMap with a java.util.Map interface, then I could do
with a new package "scala.collection.reversejcl"
["java:type:scala.collection.reversejcl.HashMap"]
dictionary AttributeMap;
Then in our Scala implementation clases I would have native Scala collections
instead. I could get the scala.collection.mutable.HashMap from a
scala.collection.reversejcl.HashMap by getting the underlying val.
This conversion between collection classes is painful and I wish we could just
work in one universe, but that isn't possible right now for us.
It seems we need set of classes that wrap the Scala collection classes but
implement the java.util.* interface. Has anybody written any such thing?
Blair
Fri, 2009-04-10, 10:07
#2
Re: Scala collection classes implementing java.util.* interfac
On Fri, Apr 10, 2009 at 8:22 AM, Blair Zajac wrote:
> It seems we need set of classes that wrap the Scala collection classes but
> implement the java.util.* interface. Has anybody written any such thing?
Lots of people ... we need it in the standard library.
I've put together a replacement for scala.collection.jcl for the 2.8.0
collections which simplifies what's there now and adds the dual
conversions. I periodically update it as the new collections evolve
and I'll submit it for inclusion when things have settled down a bit.
Cheers,
Miles
Fri, 2009-04-10, 10:17
#3
Re: Scala collection classes implementing java.util.* interfac
Awesome! Is your stuff publicly available somewhere?
--j
On Fri, Apr 10, 2009 at 3:52 AM, Miles Sabin <miles@milessabin.com> wrote:
--j
On Fri, Apr 10, 2009 at 3:52 AM, Miles Sabin <miles@milessabin.com> wrote:
On Fri, Apr 10, 2009 at 8:22 AM, Blair Zajac <blair@orcaware.com> wrote:
> It seems we need set of classes that wrap the Scala collection classes but
> implement the java.util.* interface. Has anybody written any such thing?
Lots of people ... we need it in the standard library.
I've put together a replacement for scala.collection.jcl for the 2.8.0
collections which simplifies what's there now and adds the dual
conversions. I periodically update it as the new collections evolve
and I'll submit it for inclusion when things have settled down a bit.
Cheers,
Miles
--
Miles Sabin
tel: +44 (0)7813 944 528
skype: milessabin
http://twitter.com/milessabin
Fri, 2009-04-10, 17:37
#4
Re: Scala collection classes implementing java.util.* interfac
Jorge Ortiz wrote:
> You're in luck. That's my project for the week. It's very, very, very
> pre-alpha, caveat emptor and all that good stuff, but I'd appreciate bug
> reports.
>
> You can either
> git clone git://github.com/jorgeortiz85/scala-javautils.git
>
> or download the tarballs
> http://github.com/jorgeortiz85/scala-javautils/tree/master
Great, thanks, I'll take a look at that.
Regards,
Blair
You can either
git clone git://github.com/jorgeortiz85/scala-javautils.git
or download the tarballs
http://github.com/jorgeortiz85/scala-javautils/tree/master
Compile ("mvn compile", or use your own scripts, there are no dependencies or anything), et voila:
// The Magic Line
scala> import org.scala_tools.javautils.Implicits._
import org.scala_tools.javautils.Implicits._
// Scala Map
scala> val scalaMap = scala.collection.mutable.HashMap(1 -> "one", 2 -> "two")
scalaMap: scala.collection.mutable.Map[Int,java.lang.String] = Map(2 -> two, 1 -> one)
// Wrapped into a Java Map
scala> val javaMap = scalaMap.asJava
javaMap: java.util.Map[Int,java.lang.String] = JavaWrapper(Map(2 -> two, 1 -> one))
// Works just like Java!
scala> javaMap.put(3, "three")
res1: java.lang.String = null
scala> javaMap.put(4, "four")
res2: java.lang.String = null
// The Map has been modified.
scala> javaMap
res3: java.util.Map[Int,java.lang.String] = JavaWrapper(Map(2 -> two, 4 -> four, 1 -> one, 3 -> three))
// The underlying Map was modified too!
scala> scalaMap
res4: scala.collection.mutable.Map[Int,java.lang.String] = Map(2 -> two, 4 -> four, 1 -> one, 3 -> three)
// Inverse operation! Unwraps what was previously wrapped.
scala> val reScalaMap = javaMap.asScala
reScalaMap: scala.collection.Map[Int,java.lang.String] = Map(2 -> two, 4 -> four, 1 -> one, 3 -> three)
You can turn any* Java collection into a Scala collection by calling "asScala" on it, and any* Scala collection into a Java collection by calling "asJava" on it. You can also call "foreach" (and hence use imperative for-comprehensions) on any* Java collection. Calling c.asJava.asScala should wrap then unwrap the collection. If it doesn't thats a bug. My plan is to add support for "map", "filter", and "flatMap" too.
*For some values of "any".
--j
On Fri, Apr 10, 2009 at 2:22 AM, Blair Zajac <blair@orcaware.com> wrote: