Подтвердить что ты не робот

Как преобразовать Перечисление в Seq/List в scala?

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

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

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

4b9b3361

Ответ 1

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

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)

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

Ответ 2

Текущая лучшая практика (начиная с 2.8.1) заключается в использовании scala.collection.JavaConverters

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

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

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

Ответ 3

Я не согласен с какими-либо другими ответами, но мне пришлось добавить тип, чтобы его можно было компилировать в Scala 2.9.2 и Java 7.

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

Ответ 4

Комментарий к 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

Второй элемент (name = world) отсутствует!

Я получил это, чтобы работать, используя JavaConversions.enumerationAsSaalaIterator, как упоминалось другими.

Примечание. Мне не хватает комментариев, чтобы прокомментировать сообщение Debilski.