Как преобразовать перечисление в Seq / List в Scala? - PullRequest
22 голосов
/ 03 марта 2011

Я пишу сервлет, и мне нужно получить все параметры из запроса.Я обнаружил, что request.getParameterNames возвращает java.util.Enumeration, поэтому я должен написать код:

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

Я хочу знать, есть ли способ преобразовать Enumeration в Seq/List, тогда я могуиспользовать метод map?

Ответы [ 4 ]

29 голосов
/ 03 марта 2011

Вы можете создать его самостоятельно, как это

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)

Использование последствий:

У меня есть еще один. Если вы импортируете

import scala.collection.JavaConversions._

вы можете сделать это неявно (и вы также получите неявные преобразования для других собраний Java)

request.getParameterNames.map(println)

и это просто работает.

28 голосов
/ 03 марта 2011

В настоящее время рекомендуется (* с версии 2.8.1) использовать scala.collection.JavaConverters

Этот класс отличается от JavaConversions немного, потому что преобразования не полностью автоматические, что дает вам больше контроля (это хорошо) :

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

Используя этот механизм, вы получите соответствующий и введитебезопасные преобразования для большинства типов коллекций с помощью методов asScala/asJava.

0 голосов
/ 14 ноября 2013

Комментарий к ответу Дебилски о том, что подход 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 как упомянуто другими.

Примечание. У меня недостаточно репутации, чтобы комментировать пост Дебильски.

0 голосов
/ 31 октября 2013

Я не согласен ни с одним из других ответов, но мне пришлось добавить приведение типов для компиляции в Scala 2.9.2 и Java 7.

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