Scala 中的 ListNode 实现
ListNode implementation in scala
嗨,我是 Scala 的新手,想知道如何将一个简单的 ListNode class 从 Java 重写为 Scala。
在java中,如下所示,我可以创建一个头节点head = new ListNode(0),然后设置head.next = 新的 ListNode(1)
// Java code
public class ListNode {
public int val; // data stored in this node
public ListNode next; // link to next node in the list
public ListNode(int data) {
this.val = data;
}
}
但我发现在 Scala 中很难重写相同的逻辑,下面是 ListNodeclass 的一个案例
// Scala code
case class ListNode[T](vl: T, nt: ListNode[T]) {
def value: T = vl
def next: ListNode[T] = nt
}
当我尝试实例化一个头节点并实例化另一个新节点并为其设置 head.next 时失败了:
scala> val head = ListNode(1, Nil)
<console>:9: error: type mismatch;
found : scala.collection.immutable.Nil.type
required: ListNode[?]
val head = ListNode(1, Nil)
我正在考虑将 "next list node" 放入 Option[] 中来处理 null 情况,但它似乎变得越来越复杂......在 Scala 中是否有一种简单而正确的方法来做到这一点?
非常感谢。
你的意思是null
,不是Nil
。 Nil
是一个 scala.collection.immutable.List
,但是 ListNode
构造函数不想要那个,它想要一个 ListNode
.
null 是否是表示空列表的最佳方式是另一个问题,但这就是你在 Java 代码中所做的(next
默认为 null),所以如果你在 Scala 中尝试做的是完全相同的事情,继续并使用 null。
这是一种在 Scala 中实现列表节点的方法。如果愿意,您可以轻松地将 null 替换为 Option[ListNode[T]]
。
trait ListNode[T]{
def value: T
def next: ListNode[T]
}
object ListNode{
def apply[T](item: T): ListNode[T] = new SingletonNode(item)
def apply[T](item: T, next: Option[ListNode[T]]): ListNode[T] = next match {
case Some(node) => new Node[T](item, node)
case _ => new SingletonNode(item)
}
def apply[T](item: T, next: ListNode[T]): ListNode[T] = new Node[T](item, next)
private case class SingletonNode[T](override val value: T) extends ListNode[T]{
val next: ListNode[T] = null
}
private case class Node[T](override val value: T,
override val next: ListNode[T]) extends ListNode[T]
}
一些示例用法
val ln1 = ListNode(1)
val ln2 = ListNode(1,ln1)
val ln3 = ListNode(10, ln2)
您正在混合特征定义和实际值。我认为你需要的 scala 代码只是:
case class ListNode[T](value: T, next: ListNode[T] = null)
根据用例,您可能希望将 next
更改为 Option[ListNode[T]]
and/or 如果您希望它可变,则将其定义为 var next
。
嗨,我是 Scala 的新手,想知道如何将一个简单的 ListNode class 从 Java 重写为 Scala。
在java中,如下所示,我可以创建一个头节点head = new ListNode(0),然后设置head.next = 新的 ListNode(1)
// Java code
public class ListNode {
public int val; // data stored in this node
public ListNode next; // link to next node in the list
public ListNode(int data) {
this.val = data;
}
}
但我发现在 Scala 中很难重写相同的逻辑,下面是 ListNodeclass 的一个案例
// Scala code
case class ListNode[T](vl: T, nt: ListNode[T]) {
def value: T = vl
def next: ListNode[T] = nt
}
当我尝试实例化一个头节点并实例化另一个新节点并为其设置 head.next 时失败了:
scala> val head = ListNode(1, Nil)
<console>:9: error: type mismatch;
found : scala.collection.immutable.Nil.type
required: ListNode[?]
val head = ListNode(1, Nil)
我正在考虑将 "next list node" 放入 Option[] 中来处理 null 情况,但它似乎变得越来越复杂......在 Scala 中是否有一种简单而正确的方法来做到这一点?
非常感谢。
你的意思是null
,不是Nil
。 Nil
是一个 scala.collection.immutable.List
,但是 ListNode
构造函数不想要那个,它想要一个 ListNode
.
null 是否是表示空列表的最佳方式是另一个问题,但这就是你在 Java 代码中所做的(next
默认为 null),所以如果你在 Scala 中尝试做的是完全相同的事情,继续并使用 null。
这是一种在 Scala 中实现列表节点的方法。如果愿意,您可以轻松地将 null 替换为 Option[ListNode[T]]
。
trait ListNode[T]{
def value: T
def next: ListNode[T]
}
object ListNode{
def apply[T](item: T): ListNode[T] = new SingletonNode(item)
def apply[T](item: T, next: Option[ListNode[T]]): ListNode[T] = next match {
case Some(node) => new Node[T](item, node)
case _ => new SingletonNode(item)
}
def apply[T](item: T, next: ListNode[T]): ListNode[T] = new Node[T](item, next)
private case class SingletonNode[T](override val value: T) extends ListNode[T]{
val next: ListNode[T] = null
}
private case class Node[T](override val value: T,
override val next: ListNode[T]) extends ListNode[T]
}
一些示例用法
val ln1 = ListNode(1)
val ln2 = ListNode(1,ln1)
val ln3 = ListNode(10, ln2)
您正在混合特征定义和实际值。我认为你需要的 scala 代码只是:
case class ListNode[T](value: T, next: ListNode[T] = null)
根据用例,您可能希望将 next
更改为 Option[ListNode[T]]
and/or 如果您希望它可变,则将其定义为 var next
。