Our first real test of Scala's power will be in designing a linked list, but in a functional style. This implementation will be vastly different from our implementation in Java, but understand that the differences arise from differing paradigms, not that any way is better than other.
First, we can look at re-implementing a linked list in Scala, using object-oriented practices. Scala is a hybrid language, so generally any Java construction is legal and easily translatable into Scala:
package edu.govschool.scala
/*
* By default, Scala gives us one constructor for every class we write.
* Everything in the class body that is NOT a method will be part of the
* default constructor. We can provide arguments to that constructor by
* providing the parameter list after the name of the class.
*
* By default all properties will be private values. If we need any of them
* to be mutable, we can define them using 'var'. If we want to access them
* outside of the class, we will need to define getter/setter methods as
* appropriate.
*/
class Node(data: Int, var next: Node) {
/* If a function takes no parameters, we can leave off the parentheses.
* If the return type can be inferred by the compiler (most of the time),
* then we can also leave off the return type as well. Unless the IDE tells
* you otherwise, leave off the return type.
*/
def getData = data
def getNext = next
def setNext(node: Node) = next = node
/*
* Overridden functions MUST be declared as such, otherwise you will have
* an error.
*/
override def toString = "(" + data + ")"
}
object Node {
def apply(data: Int, next: Node): Node = {
new Node(data, next)
}
}
class OOList {
var head: Node = null
var tail: Node = null
def isEmpty = head == null
def insertAtFront(data: Int): Unit = {
if (head == null) {
head = Node(data, null)
tail = head
} else {
val tmp = Node(data, head)
head = tmp
}
}
def insertAtBack(num: Int): Unit = {
if (isEmpty) {
head = Node(num, null)
tail = head
} else {
val tmp = tail
tail = Node(num, null)
tmp.setNext(tail)
}
}
def removeFromFront = {
if (isEmpty) println("Empty list")
else head = head.getNext
}
def removeFromBack = {
if (isEmpty) println("Empty list")
else if (head == tail) {
head = null
tail = head
} else {
var prev = head
var curr = head
while (curr != tail) {
prev = curr
curr = curr.getNext
}
prev.setNext(null)
tail = prev
}
}
override def toString = {
if (isEmpty) "Empty list"
else {
var tmp = head
val sb = new StringBuilder()
while (tmp != null) {
sb.append(tmp)
tmp = tmp.getNext
if (tmp != null) {
sb.append(" --> ")
}
}
sb.append("\n").toString
}
}
}
object OOList {
def apply() = new OOList()
}
object Main {
def main(args: Array[String]) = {
val l = OOList()
l.insertAtBack(1)
l.insertAtBack(2)
l.insertAtBack(3)
println(l)
}
}