在學習資料結構時學到了連結清單,因為日常工作,寫java寫多了,想換個語言玩下,就試着想用scala實作一個連結清單。哪到知道碰到很多問題,
這裡記錄下使用scala時,所遇到的那些坑。
java連結清單
首先,我們先使用java來實作一個連結清單最簡單的連結清單
public static class Node<T> {
/**
* 這裡為了友善,就不用get和set方法那一套了
*/
public Node next;
public T data;
}
public static void main(String[] args) {
Node<Integer> headNode = new Node<>();
headNode.data = 1;
Node<Integer> secondNode = new Node<>();
secondNode.data = 2;
headNode.next = secondNode;
Node<Integer> thirdNode = new Node<>();
thirdNode.data = 3;
secondNode.next = thirdNode;
Node<Integer> fourthNode = new Node<>();
fourthNode.data = 4;
thirdNode.next = fourthNode;
Node<Integer> fifthNode = new Node<>();
fifthNode.data = 5;
fourthNode.next = fifthNode;
//周遊node
Node<Integer> currentNode = headNode;
while (currentNode != null) {
System.out.println(currentNode.data);
currentNode = currentNode.next;
}
}
代碼很簡單,就不解釋了,我們使用java實作了如下的數組。

同樣的代碼,我們使用scala實作一遍。
scala連結清單
case class Node[E](var next: Node[E], var data: E) {
}
def main(args: Array[String]): Unit = {
val headNode = Node(null, 1)
val secondNode = Node(null, 2)
headNode.next = secondNode
val thirdNode = Node(null, 3)
secondNode.next = thirdNode
val fourthNode = Node(null, 4)
thirdNode.next = fourthNode
val fifthNode = Node(null, 5)
fourthNode.next = fifthNode
var currentNode = headNode
while (currentNode != null) {
println(currentNode.data)
currentNode = currentNode.next
}
}
使用scala來實作連結清單也非常簡單,除了預發以外基本上和java一模一樣。
頭部節點
好像從上面看,也沒啥問題啊。考慮這樣的情況,我們在實作一個連結清單時,經常會有一個設定一個不表示任何意義的頭結點,以便于統一連結清單的操作(add和remove操作)
先來看看使用java如何建立這樣一個“空節點”
public static class Node<T> {
/**
* 這裡為了友善,就不用get和set方法那一套了
*/
public Node next;
public T data;
}
public static class List<T>{
private Node<T> headNode = new Node<>();
}
public static void main(String[] args) {
List<Integer> list = new List<>();
}
沒啥問題
同樣的代碼,看看scala
報了個錯,Type mismatch, expected:E actual:Null ,scala的泛型不止是用于引用類型。
看這個圖可以知道,
null僅僅是AnyRef的子類
,對于AnyVal這樣的類型,比如Int,無法使用null指派。
解決方法一:限制泛型的下界
即,限制泛型必須是Null的父類型
case class Node[E](var next: Node[E], var data: E) {
}
class List[E >: Null] {
var headNode = new Node[E](null, null)
}
def main(args: Array[String]): Unit = {
val l = new List[Integer] //問題,這裡隻能用Integer,無法使用Int了
}
這種方式,解決了無法使用null指派的問題。但是使用這種方式,必須使用
new List[Integer]
無法使用基本類型比如
new List[Int]