【发布时间】:2019-03-16 07:00:30
【问题描述】:
Scala 新手在这里。我正在尝试在 Scala 中实现一个可变链表。 (有一个图书馆类可以做同样的事情——我只是把它当作一个学习练习)。到目前为止,我只支持 add() 操作。这是我的尝试:
class MutableList[T] {
class Node[T](val value: T) {
var next: Node[T] = null
def hasNext = (next != null)
}
var first, last: Node[T] = null
var size = 0
def add(value: T) = {
val newNode = new Node[T](value)
if (first == null) {
assert(size == 0)
first = newNode
} else {
last.next = newNode
}
last = newNode
size += 1
}
override def toString = {
def getValues() = {
var current = first
for (i <- 1 to size) yield {
val valStr = current.value.toString
current = current.next
valStr
}
}
getValues().mkString(",")
}
}
我知道可变数据结构并不是在 Scala 中使用/实现的最佳选择。但我只是在试验,想知道是否有更实用的 Scala 方式来编写这个?
编辑:
感谢大家提供的所有 cmets。我试图删除 nulls 并使用更多原生 Scala 构造。欢迎评论。
class MutableLinkedList[T] {
private type Node = MutableLinkedList[T]#MutableListNode
class MutableListNode(val value: T) {
var next: Option[Node] = None
}
private var first, last: Option[Node] = None
private var _size = 0
def size = _size
def add(value: T) = {
val newNode = Some(new MutableListNode(value))
first match {
case None => {
assert(_size == 0)
first = newNode
}
case Some(x) => {
assert(last.isDefined)
last.get.next = newNode
}
}
last = newNode
_size += 1
}
def head: Option[T] = {
first match {
case None => None
case Some(x) => Some(x.value)
}
}
def tail: Option[MutableLinkedList[T]] = {
first match {
case None => None
case Some(x) => {
var l = new MutableLinkedList[T]
l.first = this.first.get.next
l.last = this.last
l._size = this.size - 1
Some(l)
}
}
}
def exists(value: T): Boolean = {
var current = first
var foundIt = false
while(current.isDefined && !foundIt) {
if(current.get.value == value)
foundIt = true
current = current.get.next
}
foundIt
}
def delete(value: T): Boolean = {
var previous: Option[Node] = None
var current = first
var deleted = false
while(current.isDefined && !deleted) {
if(current.get.value == value) {
if(!previous.isDefined)
first = current.get.next
else
previous.get.next = current.get.next
_size -= 1
deleted = true
}
previous = current
current = current.get.next
}
deleted
}
override def toString = {
var current = first
var output = ""
while(current.isDefined) {
output += current.get.value.toString
current = current.get.next
if(current.isDefined)
output += ","
}
output
}
}
【问题讨论】:
-
你对“函数式 Scala”的定义是什么?对于许多排除可变状态的人以及
null。 -
也许一个好的折衷方案是 a) 仅在顶层使用
var,但Node本身是不可变的,并且 b) 要么使用Option[T]要么使用 @ 987654330@ 具有实现EmptyNode和FullNode的密封特征。 -
这个问题可能更适合codereview.stackexchange.com。
-
您好 :) 我前几次问过完全相同的问题。我有一个很好的解释,所以我放弃了here
-
按值删除意味着您只能删除具有该值的第一个元素。换句话说,使用
a,b,a,c列表,您不能删除第三个元素(第二个a)。
标签: scala