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