使用Scala检查null和integer比较的最佳方法



我在scala中有两个链表,具有以下节点类定义:

class node(_x: Int = 0, nxt: node = null) {
var x = _x
var next = nxt
}

我想将两个链表(按升序排列(合并到第三个排序列表中在Scala中最好的方法是什么

我的解决方案:

object Solution {
def mergeTwoLists(list1: node, list2: node): node = {
(list1.x >= list2.x) match {
case true => ListNode(list2.x, mergeTwoLists(list1, list2.next))
case false => ListNode(list1.x, mergeTwoLists(list2, list1.next))
}
}
}

然而,当我运行此程序时,我会得到以下2个列表的nullPointerException[1,2,4][1,3,4]

如果在函数的开头放一个println((list1, list2)),您会发现在某个时刻您正在比较Node(4,null)null


在修复它之前,您的代码充满了代码气味和不遵循Scala最佳实践的东西:

  • 在Scala中,你不应该真的得到NullPointerException,因为你不应该故意使用null。这就是选项的作用
  • 定义类时使用大写字母(即Node而非node(
  • 您的类定义过于Java化,过于复杂。它可以简化为case class Node(x: Int = 0, next: Node = null)(忽略null的错误使用(,而不需要私有/公共变量
  • 您的函数中有一个不必要的模式匹配-从技术上讲,它没有错,但在true/false上匹配而不是使用if语句有点奇怪(注意:主观(

所以要重新编写(仍然损坏的(函数,它看起来更像这样:

case class Node(x: Int = 0, next: Node = null)
def mergeTwoLists(list1: Node, list2: Node): Node = {
if (list1.x >= list2.x) {
Node(list2.x, mergeTwoLists(list1, list2.next))
} else {
Node(list1.x, mergeTwoLists(list2, list1.next))
}
}
mergeTwoLists(Node(1, Node(2, Node(4))), Node(1, Node(3, Node(4))))

开始修复:

  • 更改类定义,使第二个参数可选(以避免null(:
case class Node(x: Int = 0, next: Option[Node] = None)
  • 更改您的函数,使第二个参数成为可选参数,以说明这一点:
def mergeTwoLists(list1: Node, list2: Option[Node]): Node = {
???
}
  • 您需要知道第二个列表是否存在。如果为"无",则返回第一个列表。否则,继续:
def mergeTwoLists(list1: Node, list2: Option[Node]): Node = {
list2 match {
case None => list1
case Some(list) => ???
}
}
  • 最后,修改原始if/else以考虑节点中新的可选第二个参数:
def mergeTwoLists(list1: Node, list2: Option[Node]): Node = {
list2 match {
case None => list1
case Some(list) =>
if (list1.x >= list.x) {
Node(list.x, Some(mergeTwoLists(list1, list.next)))
} else {
Node(list1.x, Some(mergeTwoLists(list, list1.next)))
}
}
}

现在,如果你输入,你会得到一个更合理的输出:

mergeTwoLists(
Node(1, Some(Node(2, Some(Node(4))))),
Some(Node(1, Some(Node(3, Some(Node(4))))))
)

输出

Node(1,Some(Node(1,Some(Node(2,Some(Node(3,Some(Node(4,Some(Node(4,None)))))))))))

注意:我不知道这是否是";最好的";但这是如何用你已经给出的函数来解决你的问题。我还认为将变量重命名为list1list2list有点令人困惑。

它的作用:https://scastie.scala-lang.org/tUPoVzKpRRSJjZz62KsmhQ

最新更新