【问题标题】:populate immutable sequence with iterator用迭代器填充不可变序列
【发布时间】:2015-06-24 16:15:59
【问题描述】:

我正在与一些使用类似迭代器的功能的 Java 代码进行互操作,并假设您将继续测试它的 .next 是否为空值。我想将其放入不可变的 Scala 数据结构中,以便通过函数式编程对其进行推理。

现在,我正在填充可变数据结构,然后将它们转换为不可变数据结构。我知道有一种更实用的方法可以做到这一点。

如何在不使用中间可变集合的情况下重构以下代码以填充不可变数据结构?

谢谢

{
 val sentences = MutableList[Seq[Token]]()
 while(this.next() != null){
   val sentence = MutableList[Token]()
   var token = this.next()
   while(token.next != null){
     sentence += token
     token = token.next
   }
   sentences += sentence.to[Seq]
 }
 sentences.to[Seq]
}

【问题讨论】:

  • Iterator 有一个 toList 和一个 toSeq 方法。
  • 直接把Java迭代器转成Scala迭代器和takeWhile(_ != null)不是更简单吗?
  • 它不是 scala 或 java 迭代器。它们是行为类似于迭代器的自定义 java 类,除了没有 .hasNext —— 你应该检查 .next 以获取 null 值。
  • @WalrustheCat 哦,好吧,如果它本身不是迭代器,只是看起来像它的东西,那么我想你的解决方案应该可以工作。您可以创建自己的 Scala 迭代器,并将当前实现作为它的主体,这应该更容易从 Scala 端使用...
  • @PatrykĆwiek 谢谢——无法想象。愿意发表您的评论作为答案吗?

标签: scala iterator immutability


【解决方案1】:

您可以尝试使用Iterator.iterate 方法来模拟真正的迭代器,然后使用标准的收集方法,如takeWhiletoSeq。我对thisnext 的类型并不完全清楚,但是这些方面的东西可能会起作用:

Iterator.iterate(this){ _.next }.takeWhile{ _ != null }.map { sentence =>
    Iterator.iterate(sentence.next) { _.next }.takeWhile{ _ != null }.toSeq
}.toSeq

您还可以通过定义自己的nexthasNext 方法来扩展Iterable,以便更轻松地使用这些标准方法。您甚至可以定义从这些 Java 类型到这个新的Iterable 类型的隐式或显式转换——这与您在JavaConversionsJavaConverters 中看到的模式相同

【讨论】:

  • 非常感谢。仔细观察,这些 java 类实际上是链表。这会改变你的实现吗?
  • 如果你有java.util.LinkedList,你绝对应该考虑使用scala.collection.JavaConversionsscala.collection.JavaConverters 中的帮助器,它们是专为这种情况而设计的。例如,如果您导入scala.collection.JavaConverters._,则可以调用myLinkedList.asScala 来获取scala.collection.mutable.Buffer,这将解锁Scala 集合库的所有功能。
  • 嘿@Ben Riech,不幸的是,它们不是java.util.LinkedLists,它们是满足链表契约的自定义Java 类。感谢您的意见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
  • 2021-01-04
  • 2013-04-23
  • 2021-07-19
相关资源
最近更新 更多