【问题标题】:How to find and remove an element from Scala ListBuffer?如何从 Scala ListBuffer 中查找和删除元素?
【发布时间】:2018-11-18 01:14:56
【问题描述】:

以下代码使用 Scala 2.12.7 和 Java 11.0.1 引发 UnsupportedOperationException

listBuffer
.iterator
.dropWhile(_ != u)
.asJava
.remove()

为什么? ListBuffer 是可变的,在遍历时使用 Iterator 删除元素应该是有效的。 ListBuffer 包含 Int

java.lang.UnsupportedOperationException was thrown.
java.lang.UnsupportedOperationException
    at scala.collection.convert.Wrappers$IteratorWrapper.remove(Wrappers.scala:31)
    at scala.collection.convert.Wrappers$IteratorWrapper.remove(Wrappers.scala:26)
    at week4.UndirectedGraph.$anonfun$removeVertex$2(UndirectedGraph.scala:52)
    at scala.runtime.java8.JFunction1$mcVI$sp.apply(JFunction1$mcVI$sp.java:12)
    at scala.collection.immutable.List.foreach(List.scala:388)
    at scala.collection.generic.TraversableForwarder.foreach(TraversableForwarder.scala:34)
    at scala.collection.generic.TraversableForwarder.foreach$(TraversableForwarder.scala:34)
    at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:43)
    at week4.UndirectedGraph.$anonfun$removeVertex$1(UndirectedGraph.scala:50)

编辑: 不是this 问题的重复,因为问题是试图在结构上修改Arrays.asList 返回的列表。如果不是针对不知道答案但通常是第一个尝试将问题作为重复问题关闭的人,我不应该说显而易见的事情。

【问题讨论】:

标签: java scala collections iterator


【解决方案1】:

这是引发错误的source 代码:

 case class IteratorWrapper[A](underlying: Iterator[A]) extends ju.Iterator[A] with ju.Enumeration[A] {
    def hasNext = underlying.hasNext
    def next() = underlying.next()
    def hasMoreElements = underlying.hasNext
    def nextElement() = underlying.next()
    override def remove() = throw new UnsupportedOperationException
  }

请注意,它不关心底层集合是否可变。

我认为这种实现是有道理的。 Scala 迭代器在设计上不支持remove();它们向 Java 的转换也应该产生行为相同的迭代器。

【讨论】:

  • “迭代器在设计上不支持remove”——你有这方面的参考吗?我在docs 中没有看到任何此类声明
  • @AbhijitSarkar, 1) 在Scaladocs 中没有提到remove。 2)Iterator trait 没有定义remove
【解决方案2】:

不是直接回答您的问题,而是一种解决方案,以防您只需要根据对象相等性删除元素,就像在您的示例代码中一样:

使用ListBuffer-= 方法。这会从 ListBuffer 中删除所有出现的元素,而不创建结构的副本。

  def main(args: Array[String]): Unit = {
    val u = 999
    val listBuffer = new ListBuffer[Int]
    listBuffer ++= Seq(1, 7, 3, 8, 0, 3, 6, 7, 999, 5, 7, 8, 999, 1, 5, 999)
    println(listBuffer)
    listBuffer -= u
    println(listBuffer)
  }

如果您使用filter 方法,则可以使用谓词,但会创建ListBuffer 的副本:

  def main(args: Array[String]): Unit = {
    val u = 999
    var listBuffer = new ListBuffer[Int]
    listBuffer ++= Seq(1, 7, 3, 8, 0, 3, 6, 7, 999, 5, 7, 8, 999, 1, 5, 999)
    println(listBuffer)
    listBuffer = listBuffer.filter(_ != u)
    println(listBuffer)
  }

【讨论】:

  • -= 使用对象相等性来查找和删除元素,而不是谓词
猜你喜欢
  • 2012-10-07
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 1970-01-01
相关资源
最近更新 更多