6

I'm using the Java Twitter4J library in a Scala project.

I'm calling the method

twitter.getFriendsStatuses()

This method returns a list of twitter4j.User objects containing statuses.

I try to iterate over them and it goes in an infinite loop over the first element:

val users:List[User] = twitter.getFriendsStatuses(userId, paging.getSinceId())
while( users.iterator.hasNext() ) {
  println(users.iterator.next().getStatus())
}

Any ideas?

Sri
  • 5,805
  • 10
  • 50
  • 68

5 Answers5

27

I guess users.iterator produces the new iterator each time it's evaluated. Try this:

val it = users.iterator
while(it.hasNext() ) {
   println(it.next().getStatus())
}
axtavt
  • 239,438
  • 41
  • 511
  • 482
18

If you use Scala 2.8, you could use JavaConversion to convert Java collection to Scala collection automatically.

Ex.

import scala.collection.JavaConversions._

// Java Collection
val arrayList = new java.util.ArrayList[Int]
arrayList.add(2)
arrayList.add(3)
arrayList.add(4)

// It will implicitly covert to Scala collection, 
// so you could use map/foreach...etc.
arrayList.map(_ * 2).foreach(println)
Brian Hsu
  • 8,781
  • 3
  • 47
  • 59
8

What's wrong with just

users.foreach(user => println(user.getStatus()))

or even

users.map(_.getStatus()).foreach(println _)

or, if you're worried about traversing the collection twice

users.view.map(_.getStatus()).foreach(println _)

IOW: Why do you want to manage the iteration yourself (and possibly make mistakes), when you can just let someone else do the work for you?

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Nothing's wrong. I've just begun learning Scala. Thanks for the examples! PS: These are Java Lists, will check if your examples work. – Sri Mar 14 '11 at 14:53
  • Nope, sorry. Twitter4J returns me a java.util.List and .foreach, .map, .view.map don't work out of the box. Is there some neat way to convert these into Scala Lists and make use of .foreach, .map and .view's? – Sri Mar 14 '11 at 14:56
  • 5
    @Srirangan: `import collection.JavaConversions._` and it will work. – missingfaktor Mar 14 '11 at 16:12
4

I prefer scalaj-collection to scala.collection.JavaConversions. This makes the conversions explicit:

import scalaj.collection.Implicits._

val arrayList = new java.util.ArrayList[Int]
arrayList.add(2)
arrayList.add(3)
arrayList.add(4)

arrayList.asScala.map(_ * 2).foreach(println)

Available here: https://github.com/scalaj/scalaj-collection

Kris Nuttycombe
  • 4,560
  • 1
  • 26
  • 29
  • 1
    I didn't know about scalaj-collection, but in Scala 2.8, at least, `import scala.collection.JavaConverters._` will give you explicit `.asScala`conversions if you want them. – Nicolas Payette Mar 14 '11 at 19:02
  • Yeah, I'd heard about that but haven't had the time to really look into the implementation of JavaConverters. scalaj-collection is pretty clean, so I've kind of stuck to that. – Kris Nuttycombe Mar 14 '11 at 21:27
1

I suggest using

scala.collection.JavaConverters._

and simply add .asScala to every object you wish to iterate

Ohad Navon
  • 1,693
  • 1
  • 14
  • 19