如何在枚举中将枚举转换为Seq / List?

时间:2011-03-03 16:44:01

标签: scala enumeration

我正在编写一个servlet,需要从请求中获取所有参数。我发现request.getParameterNames返回java.util.Enumeration,因此我必须将代码编写为:

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

我想知道有没有办法将Enumeration转换为Seq/List,然后我可以使用map方法?

4 个答案:

答案 0 :(得分:28)

您可以像这样自己构建

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

Iterator.continually(names, names.nextElement)上执行按名称调用,该调用在每一步返回原始枚举和下一个元素。停止条件当然是takeWhile,因为我们不需要永远绕过枚举,我们map只有值。

或者,您可以构建一个包装器:

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

或者,最后,这是内置方法,可能是在这种情况下使用的方法:

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

使用Implicits:

我还有一个。如果导入

import scala.collection.JavaConversions._

你可以隐式地做(并且你也会获得其他Java集合的隐式转换)

request.getParameterNames.map(println)

它只是有效。

答案 1 :(得分:27)

目前的最佳做法(自2.8.1开始)是使用scala.collection.JavaConverters

此类与JavaConversions略有不同,因为转换不是完全自动的,为您提供更多控制(这是一件好事)

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

使用此机制,您可以通过asScala/asJava方法为大多数集合类型获得适当且类型安全的转换。

答案 2 :(得分:0)

我不同意任何其他答案,但我必须添加一个类型转换,以便在Scala 2.9.2和Java 7中进行编译。

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

答案 3 :(得分:0)

评论Debilski的答案,即Iterator.continually方法错误,因为它错过了最后一个条目。这是我的测试:

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) }

输出

name=hello

缺少第二项(名称=世界)!

我通过使用其他人提到的JavaConversions.enumerationAsScalaIterator来实现这一点。

注意我没有足够的代表直接评论Debilski的帖子。