【问题标题】:How to convert Enumeration to Seq/List in scala?如何在scala中将枚举转换为Seq/List?
【发布时间】:2011-03-03 16:44:01
【问题描述】:

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

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

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

【问题讨论】:

    标签: scala enumeration


    【解决方案1】:

    使用 JavaConverters

    https://stackoverflow.com/a/5184386/133106

    使用包装迭代器

    你可以建立一个包装器:

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

    使用 JavaConversions 包装器

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

    使用 JavaConversions 隐式

    如果你导入

    import scala.collection.JavaConversions._
    

    您可以隐式执行(您还将获得其他 Java 集合的隐式转换)

    request.getParameterNames.map(println)
    

    使用 Iterator.continually

    您可能很想使用 Iterator.continually 构建迭代器,就像建议的此答案的早期版本一样:

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

    但这是不正确的,因为枚举数的最后一个元素将被丢弃。 原因是takeWhile中的hasMoreElement调用是在continually中调用nextElement之后执行的,从而丢弃了最后一个值。

    【讨论】:

    • 我认为第一个代码包含一个错误:它没有返回最后一个元素。要得到它,你应该做类似val nameIterator = Iterator.continually((names.hasMoreElements, names)).takeWhile(_._1).map(_._2.nextElement)
    • 请注意,JavaConversions 已弃用。请参阅 Kevin Wright 的回答。
    【解决方案2】:

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

    这个类与JavaConversions略有不同,因为转换不是全自动的,给你更多的控制(这是一件好事)

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

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

    【讨论】:

    • asScala 出于某种原因对我不起作用。我用enumerationAsScalaIterator(enumeration)
    • @Mygod 你做了import 吗?你需要它来获得隐含。
    • 看来现在需要import scala.collection.JavaConverters._
    【解决方案3】:

    对 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.enumerationAsScalaIterator 来实现这一点。

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2017-10-06
        • 2011-03-30
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多