How to convert Enumeration to Seq/List in scala?

别说谁变了你拦得住时间么 提交于 2019-12-21 07:07:34

问题


I'm writing a servlet, and need to get all parameters from the request. I found request.getParameterNames returns a java.util.Enumeration, so I have to write code as:

val names = request.getParameterNames
while(names.hasMoreElements) {
    val name = names.nextElement
}

I wanna know is there any way to convert a Enumeration to a Seq/List, then I can use the map method?


回答1:


You can build it yourself like this

val nameIterator = Iterator.continually((names, names.nextElement)).takeWhile(_._1.hasMoreElements).map(_._2)

Iterator.continually performs a by-name call on (names, names.nextElement) which at each step returns the original enumeration and the next element. The stopping condition is of course in the takeWhile and because we don’t need passing around the enumeration forever, we map only the values.

Alternatively, you could build up a wrapper:

val nameIterator = new Iterator[SomeType] { def hasNext = names.hasMoreElements; def next = names.nextElement }

Or, finally, and this is the built-in method and probably the one to use in this case:

val nameIterator = new scala.collection.JavaConversions.JEnumerationWrapper(names)

Using Implicits:

I’ve got one more. If you import

import scala.collection.JavaConversions._

you can do it implicitly (and you’ll also get implicit conversions for other Java collecitons)

request.getParameterNames.map(println)

and it just works.




回答2:


Current best practice (since 2.8.1) is to use scala.collection.JavaConverters

  • Scaladoc here

This class differs from JavaConversions slightly, in that the conversions are not fully automatic, giving you more control (this is a good thing):

import collection.JavaConverters._
val names = ...
val nameIterator = names.asScala

Using this mechanism, you'll get appropriate and type-safe conversions for most collection types via the asScala/asJava methods.




回答3:


I don't disagree with any of the other answers but I had to add a type cast to get this to compile in Scala 2.9.2 and Java 7.

import scala.collection.JavaConversions._
...
val names=request.getParameterNames.asInstanceOf[java.util.Enumeration[String]].toSet



回答4:


A comment on Debilski's answer that the Iterator.continually approach is wrong because it misses the last entry. Here's my test:

val list = new java.util.ArrayList[String]
list.add("hello")
list.add("world")
val en = java.util.Collections.enumeration(list)
val names = Iterator.continually((en, en.nextElement)).takeWhile(_._1.hasMoreElements).map(_._2)
    .foreach { name => println("name=" + name) }

Output is

name=hello

The second item (name=world) is missing!

I got this to work by using JavaConversions.enumerationAsScalaIterator as mentioned by others.

Note I don't have enough rep to comment on Debilski's post directly.



来源:https://stackoverflow.com/questions/5183730/how-to-convert-enumeration-to-seq-list-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!