Scala中的LinkedList

时间:2016-12-07 15:53:15

标签: scala linked-list

为了练习,我正在尝试在Scala中实现LinkedList

主要问题是关于Null参考。

但首先是一些代码:

class Node(xkey: String, xnext: Option[Node], xinfo: Int) {
  val key: String = xkey;
  var next = xnext.getOrElse(None);
  var info: Int = xinfo;

  def this(xkey: String, xinfo: Int) {
    this(xkey, None, xinfo);
  }

  def this(xkey: String) {
    this(xkey, None, -1);
  }

  @Override
  override def toString: String = key + ":" + info
}

此时,我已经开始关注事情了。 我在构造中将xnext声明为Option[Node],因为此linkedList中的尾部没有下一个。

在我的第一次尝试中,它只是一个Node,但是有了null对象的问题,因为编译器只是告诉我“null无法转换为Node”(或类似的东西,我现在不记得了) ) - 所以我切换到这个选项。

但是,可以吗?因为,您知道,对我而言,接下来应该是Node,而不是Option,否则,我不知道,linkedList如何引用下一个节点。

无论如何,第二类(即我的链接列表)

class LinkedNode {

  private var first: Option[Node] = None;
  private var last: Option[Node] = None;

  def addNode(newNode: Node) = {
    if (first == null) {
      first = Some(newNode);
      last = Some(newNode);
      first.next = last;
    }
    else {
      last.next = newNode;
      newNode.next = null;
      last = newNode
    }
  }

  def size(): Long = {
    var currentNode : = first;
    var size = 0L;
    while (currentNode != null) {
      size+=1;
      currentNode = currentNode.next;
    }
    size
  }

  def findNodeByKey(key: String) : Node = {
    var currentNode = first;
    while(currentNode != null) {
      if (currentNode.key.equals(key))
        currentNode
      else {
        currentNode = currentNode.next;
      }
    }
    currentNode;
  }

  def delNodeByKey(key : String) : Boolean = {
    var currentNode = first;
    var previousNode = first;
    while(currentNode != null) {
      if (currentNode.key.equals(key)) {
        previousNode = currentNode.next;
        return true;
      }
      previousNode = currentNode;
      currentNode = currentNode.next;
    }
    return false;
  }


}

没什么。我已经阻止了我的构造函数因为第一个也是最后一个。

我该如何申报? Node?或Option[Node]
Add方法也存在问题 当我添加节点时,我想添加Node对象,而不是Option[Node] 而且我无法了解如何使用所有OptionSomeNone类来实现我想要的内容。

我知道我的要求不应该这么模糊,但是有什么帮助吗?

P.S。我已经阅读了this Q/A但它没有帮助我

1 个答案:

答案 0 :(得分:3)

  

此时,我已经开始关注事情了。我将构造中的xnext声明为Option [Node],因为此linkedList中的尾部没有下一个。   [...]   但是,好吗?因为,你知道,对我而言,接下来应该是Node,而不是Option,否则,我不知道,在linkedList中如何引用下一个Node。

这是替换null的一个很好的解决方案,您肯定希望这样做以防止空指针异常等。 Option[Node]只是包含在容器中的Node(或None)。您可以检查它是否具有isEmpty的值,或者使用get获取其值(如果Option为空,则会抛出异常)。

null的唯一区别在于,您需要检查isEmpty是否option.get而不是检查null,并且需要打开({1}} None)当您确定它不是option match { case Some(x) => println(x) case None => println("Whoops, no value :(") } 时,它会明确地显示。

从选项中检索值的更典型(scala-typical)方法是模式匹配:

Option[Node]

关于你的其他问题,它们确实有点模糊。

  

我该如何判断它们?节点?或选项[节点]?

如果存在变量没有值的可能性,请使用null(例如,如果您有时在Java中将其设置为Option[Node]。)

  

当我添加节点时,我想添加一个Node对象,而不是Option [Node]。

不,您想在内部添加Option[Node].isEmpty,因为稍后需要检查节点是否已设置。在Scala中,与设置为null相比,最好通过addNode执行此操作。您已经在代码的某些部分(例如Some(newNode))执行了此操作,您可以addNode(我称之为"将节点包装在选项& #34;,但我不完全确定这是否是正确的术语。

  

我无法通过所有Option,Some和None课程获得如何实现我想要的东西。

您在null中所做的事情在某种程度上似乎是正确的,但您却试图在else分支中再次使用// We don't need Option[Node] for the parameter, because there // _must_ be a Node value to be added def addNode(newNode: Node) = { if (first.isEmpty) { first = Some(newNode) last = Some(newNode) first.next = last } else { newNode.next = None last.next = Some(newNode) last = Some(newNode) } } 。怎么样:

def send_commands(conn):
    while True:
        cmd = input()
        if cmd == 'quit':
            conn.close()
            s.close()
            sys.exit()
        if len(str.encode(cmd)) > 0:
            conn.send(str.encode(cmd))
            client_response = str(conn.recv(1024), "utf-8")
            print(client_response, end="")

(我没有运行该代码,也没有彻底检查您的逻辑)