使用 Scala 检查 null 和整数比较的最佳方法
best way to check for null and integer comparison using Scala
我在 Scala 中有 2 个链表,节点 class 定义如下:
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
。这就是选项的用途。
- 定义 classes 时使用大写字母(即
Node
over node
)。
- 你的 class 定义太过 Java-y 和 over-complicated。它可以简化为
case class Node(x: Int = 0, next: Node = null)
(忽略 null
的不正确使用)而无需 private/public 变量 stuff.
- 您的函数中有一个不必要的模式匹配 - 它在技术上没有任何问题,但是在 true/false 上匹配而不是使用
if
语句有点奇怪(注意:主观)。
所以 re-write 你的(仍然损坏的)功能,它看起来更像这样:
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))))
关于修复它:
- 更改 class 定义以使第二个参数可选(以避免
null
):
case class Node(x: Int = 0, next: Option[Node] = None)
- 更改您的函数,使第二个参数可选以解决此问题:
def mergeTwoLists(list1: Node, list2: Option[Node]): Node = {
???
}
- 您需要知道第二个列表是否存在。如果是 None,则只 return 第一个列表。否则,继续:
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)))))))))))
注意:我不知道这是否是“最佳”方式,但它是如何使用您已经提供的功能解决您的问题。我还考虑将变量重命名为 list1
、list2
和 list
有点令人困惑。
Scastie 正在工作:https://scastie.scala-lang.org/tUPoVzKpRRSJjZz62KsmhQ
我在 Scala 中有 2 个链表,节点 class 定义如下:
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
。这就是选项的用途。 - 定义 classes 时使用大写字母(即
Node
overnode
)。 - 你的 class 定义太过 Java-y 和 over-complicated。它可以简化为
case class Node(x: Int = 0, next: Node = null)
(忽略null
的不正确使用)而无需 private/public 变量 stuff. - 您的函数中有一个不必要的模式匹配 - 它在技术上没有任何问题,但是在 true/false 上匹配而不是使用
if
语句有点奇怪(注意:主观)。
所以 re-write 你的(仍然损坏的)功能,它看起来更像这样:
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))))
关于修复它:
- 更改 class 定义以使第二个参数可选(以避免
null
):
case class Node(x: Int = 0, next: Option[Node] = None)
- 更改您的函数,使第二个参数可选以解决此问题:
def mergeTwoLists(list1: Node, list2: Option[Node]): Node = {
???
}
- 您需要知道第二个列表是否存在。如果是 None,则只 return 第一个列表。否则,继续:
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)))))))))))
注意:我不知道这是否是“最佳”方式,但它是如何使用您已经提供的功能解决您的问题。我还考虑将变量重命名为 list1
、list2
和 list
有点令人困惑。
Scastie 正在工作:https://scastie.scala-lang.org/tUPoVzKpRRSJjZz62KsmhQ