Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to instantiate and populate a Scala Stream in Java?

Tags:

java

scala

I have a Scala function foo(bs : Stream[Bar]) : Bat that I need to call from Java code. How do I create the "bs" Stream (Stream[Bar]) in Java and lazily generate its Bar objects?

like image 557
Larry OBrien Avatar asked Sep 23 '11 19:09

Larry OBrien


People also ask

How do you create a stream in Scala?

In scala a List can be constructed with :: operator, whereas a Stream can be constructed with the #:: operator method, using Stream. empty at the end of the expression. In above syntax the head of this stream is 1, and the tail of it has 2 and 3.

Does scala have Streams?

Scala has several data structures to support lazy operations: Stream, Iterator, and View.


2 Answers

The best way is to use one of the factories available on Stream object companion. For the most useful of them, you'll need to implement Function1 as well, which can be done by extending AbstractFunction1.

Here's an example:

import scala.collection.immutable.Stream;
import scala.runtime.AbstractFunction1;

public class Ex {
    public Stream<Integer> stream = Stream.iterate(0, new Increment());
}

class Increment extends AbstractFunction1<Integer, Integer> {
    public Integer apply(Integer v1) {
        return v1 + 1;
    }
}
like image 98
Daniel C. Sobral Avatar answered Oct 14 '22 15:10

Daniel C. Sobral


Depending on what needs to be in the stream, it might be easiest to create a java.util.Iterator and then convert this to a Stream via a scala.collection.Iterator:

import scala.collection.JavaConverters;
import scala.collection.immutable.Stream;

...

List<String> list = new ArrayList<String>();

\\ Fill the list somehow...

Iterator<String> it = list.iterator();

Stream<String> stream = JavaConverters.asScalaIteratorConverter(it)
                                      .asScala().toStream();

The iterator doesn't have to come from a collection, of course—we can just as easily create an infinite stream by implementing our own iterator:

Stream<String> stream = JavaConverters.asScalaIteratorConverter(
  new Iterator<String>() {
    int i = 0;
    public boolean hasNext() { return true; }
    public void remove() { throw new UnsupportedOperationException(); }
    public String next() { return Integer.toString(i++); }
  }
).asScala().toStream();

It's not as pretty as something like Stream.iterate(0)(_ + 1).map(_.toString), but it works.

like image 20
Travis Brown Avatar answered Oct 14 '22 14:10

Travis Brown