Dan Gravell
Dan Gravell

Reputation: 8240

Equivalent of Iterator.continually for an Iterable?

I need to produce an java.lang.Iterable[T] where the supply of T is some long running operation. In addition, after T is supplied it is wrapped and further computation is made to prepare for the next iteration.

Initially I thought I could do this with Iterator.continually. However, calling toIterable on the result actually creates a Stream[T] - with the problem being that the head is eagerly evaluated, which I don't want.

How can I either:

  1. Create an Iterable[T] from a supplying function or
  2. Convert an Iterator[T] into an Iterable[T] without using Stream?

Upvotes: 1

Views: 1279

Answers (2)

Dan Gravell
Dan Gravell

Reputation: 8240

Because java.lang.Iterable is a very simple API, it's trivial to go from a scala.collection.Iterator to it.

case class IterableFromIterator[T](override val iterator:java.util.Iterator[T]) extends java.lang.Iterable[T]
val iterable:java.lang.Iterable[T] = IterableFromIterator(Iterator.continually(...).asJava)

Note this contradicts the expectation that iterable.iterator() produces a fresh Iterator each time; instead, iterable.iterator() can only be called once.

Upvotes: 1

Brian McCutchon
Brian McCutchon

Reputation: 8584

In Scala 2.13, you can use LazyList:

LazyList.continually(1)

Unlike Stream, LazyList is also lazy in its head.

Upvotes: 2

Related Questions