2

I am trying to build a hashmap from pairs returned in a jdbc call using the following code

val query = "select x,y from tablename"
val rs = stmt.executeQuery(query)
var lookup = new HashMap[String,String]()
while(rs.next()) {
  lookup = lookup + (rs.getString(1)-> rs.getString(2))
}

and getting a cast exception.

scala.collection.immutable.HashMap cannot be cast to scala.runtime.Nothing$

How might this be fixed and what is going on? Is there a better, more Scala like way to handle this like maybe something using a builder? Thanks for any help.

Slayer6
  • 121
  • 6
  • In this code I can't see anything that could lead to this exception. Which line is it pointing to, exactly? – Alexey Romanov Nov 04 '17 at 21:19
  • The code is being executed within a streamsets stage. It's kindof a container and implements an interface which unfortunately can obscure some of the error reporting. As this is the only hashmap being used, it must be the line that appends to the map. Is there a better way to write this? Could you explain what this exactly means? Thanks – Slayer6 Nov 04 '17 at 22:02

1 Answers1

7

You are writing java code in scala. Don't. Either switch to java, or take a a few moments to learn real scala. You will not regret it.

 Iterator
  .continually(rs.next)
  .takeWhile(identity)
  .map { _ => rs.getString(1) -> rs.getString(2) }
  .toMap
Dima
  • 39,570
  • 6
  • 44
  • 70
  • I'd replace takeWhile(identity) with takeWhile(rs.hasNext) though – Jagat Nov 05 '17 at 22:01
  • @Jagat no, `ResultSet` isn't an `Iterator`. There is no `hasNext`. You just keep calling `next`, until it returns `false`. – Dima Nov 06 '17 at 11:52
  • Thanks Dima. Trying to get this to work. I do not see that Iterator.iterate has a takeWhile (cannot resolve Symbol). Also, how does "identity" work? Sorry for my confusion. This is the type of solution I was hoping for. – Slayer6 Nov 06 '17 at 18:34
  • @Slayer6 sorry, fixed that (it needs to be `.continualy`, not `.iterate`). As to the `identity`, it's just a function, that returns its own argument: `def identity[T](x: T)=x`. In this case, it will be returning `true` until `rs.next` turns to `false`. – Dima Nov 06 '17 at 19:23
  • Great Thanks Dima. I had resorted to val builder = scala.collection.immutable.HashMap.newBuilder[String,String] while(rs.next) { builder+=rs.getString(1)->rs.getString(2) } but will switch to the iterator. – Slayer6 Nov 06 '17 at 21:38
  • don't use builders. They are intended for implementing new collections, not for application use. – Dima Nov 06 '17 at 22:32