1
votes

I'm interoperating with some Java code that uses iterator-like functionality, and presumes you will continue to test it's .next for null values. I want to put it into immutable Scala data structures to reason about it with functional programming.

Right now, I'm filling mutable data structures and then converting them to immutable data structures. I know there's a more functional way to do this.

How can I refactor the code below to populate the immutable data structures without using intermediate mutable collections?

Thanks

{
 val sentences = MutableList[Seq[Token]]()
 while(this.next() != null){
   val sentence = MutableList[Token]()
   var token = this.next()
   while(token.next != null){
     sentence += token
     token = token.next
   }
   sentences += sentence.to[Seq]
 }
 sentences.to[Seq]
}
1
Iterator has a toList and a toSeq method. - Peter Neyens
Wouldn't it be easier to just directly convert the Java iterator to Scala iterator and takeWhile(_ != null)? - Patryk Ćwiek
It's not a scala or java iterator. They are custom java classes that behave like iterators, except without .hasNext -- you're expected to check .next for null values. - Walrus the Cat
@WalrustheCat Oh well, if it's not an iterator per se, just something that kind of looks like it, then I guess your solution should work. You can create your own Scala iterator with your current implementation as its body, which should make it easier to use from Scala side... - Patryk Ćwiek
@PatrykĆwiek Thanks -- can't visualize that. Care to post your comment as an answer? - Walrus the Cat

1 Answers

1
votes

You might try to use the Iterator.iterate method in order to simulate a real iterator, and then use standard collection methods like takeWhile and toSeq. I'm not totally clear on the type of this and next, but something along these lines might work:

Iterator.iterate(this){ _.next }.takeWhile{ _ != null }.map { sentence =>
    Iterator.iterate(sentence.next) { _.next }.takeWhile{ _ != null }.toSeq
}.toSeq

You can also extend Iterable by defining your own next and hasNext method in order to use these standard methods more easily. You might even define an implicit or explicit conversion from these Java types to this new Iterable type – this is the same pattern you see in JavaConversions and JavaConverters