2011-03-03 77 views
20

我正在写一个servlet,并且需要从请求中获取所有参数。我发现request.getParameterNames返回java.util.Enumeration,所以我必须写代码:如何将枚举转换为Seq/List在Scala中?

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

我想知道有没有什么办法来转换EnumerationSeq/List,然后我就可以使用map方法?

回答

27

你可以自己来建立这样的

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

request.getParameterNames.map(println) 

,它就可以工作。

+0

我认为第一个代码包含一个bug:它不会返回最后一个元素。为了得到它,你应该做'val nameIterator = Iterator.continually((names.hasMoreElements,names))。takeWhile(_._ 1).map(_._ 2.nextElement)' – SergGr 2017-05-04 23:12:58

+0

请注意'JavaConversions'已被弃用。见Kevin Wright的回答。 – Kelvin 2017-09-27 21:57:05

23

当前的最佳实践(自2.8.1)是使用scala.collection.JavaConverters

这个类JavaConversions稍有不同,在该转换是不是全自动的,给你更多的控制(这是一件好事)

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

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

+0

'asScala'由于某种原因不适合我。我使用了'enumerationAsScalaIterator(枚举)'。 – Mygod 2016-05-07 03:56:13

+0

@Mygod你做了'进口'吗?你需要它来获得暗示。 – Kelvin 2017-09-27 21:58:14

0

我不与任何其他的答案不同意,但我不得不添加一个类型转换得到这个斯卡拉2.9.2编译和Java 7

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

上Debilski的回答的评价是Iterator.continuous方法是错误的,因为它错过了最后一个条目。下面是我的测试:

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的帖子。