Carcigenicate

Scala Linked List using the Null Object Pattern

Dec 11th, 2014
352
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.93 KB | None | 0 0
  1. package tutorial
  2.  
  3. class RNode[+A] {
  4.    
  5.     //My attempt to abstract away case matching
  6.     def ifNullThenElse[B >: A,C](ifNull:C,ifNot:Node[A]=>C): C =
  7.         this match {
  8.             case NullNode       => ifNull
  9.             case node:Node[B]   => ifNot(node)
  10.         }
  11.    
  12.     //Its use
  13.     def hasNext [B >: A]: Boolean =
  14.         ifNullThenElse(false, { case Node(_,n) =>
  15.             n != null })
  16.            
  17.     def findLast[B >: A]: RNode[B] =
  18.         ifNullThenElse(NullNode,{ node:Node[B] =>
  19.             if (node.hasNext) (getNext.findLast)
  20.             else node })
  21.  
  22.     def getNext[B >: A]: RNode[B] =
  23.         ifNullThenElse(NullNode,{ case Node(_,n) => n })
  24.    
  25.    
  26.     def foreach[B >: A, C](f: B => C): RNode[C] =
  27.         ifNullThenElse(NullNode,{ case Node(c,n) =>
  28.             Node( f(c) , n.foreach(f) ) })
  29.    
  30.     def replaceTail[B >: A](newTail:RNode[B]): RNode[B] =
  31.         ifNullThenElse(newTail,{ case Node(c,n) =>
  32.             Node( c , newTail ) })
  33.            
  34.     def unsafeGetCargo[B >: A]: B =
  35.         ifNullThenElse(throw new Exception("getCargo called on a NullNode"),
  36.             { case Node(c,n) => c })
  37.            
  38.     def safeGetCargo[B >: A]: Option[B] =
  39.         ifNullThenElse(None,{ case Node(c,n) => Some(c) })
  40. }
  41.  
  42. case class Node[+A](cargo:A,next:RNode[A] = NullNode) extends RNode[A]
  43.  
  44. case object NullNode extends RNode[Nothing]
  45.  
  46. class LinkedList[A] {
  47.     var head: RNode[A] = NullNode
  48.     var last: RNode[A] = head
  49.     var size: Int = 0
  50.    
  51.     def this(head:RNode[A], last:RNode[A]) = {
  52.         this
  53.         this.head = head
  54.         this.last = last
  55.     }
  56.    
  57.     def length: Int = size
  58.     def maxIndex: Int = size - 1
  59.    
  60.     def pushFront(cargo:A) = {
  61.         val oldHead = head
  62.         head = Node(cargo).replaceTail(oldHead)
  63.         size += 1
  64.     }
  65.    
  66.     def pushBack(cargo:A) = {
  67.         last.replaceTail(Node(cargo))
  68.         last = last.getNext
  69.         size += 1
  70.     }
  71.    
  72.     def foreach[B](f: A => B): LinkedList[B] = {
  73.         val newHead = head.foreach(f)
  74.         new LinkedList(newHead, newHead.findLast)
  75.     }
  76.    
  77.     def get(index:Int): A = {
  78.         var curNode = head
  79.         for (i <- 0 to maxIndex) {
  80.             curNode = curNode.getNext
  81.         }
  82.         curNode.unsafeGetCargo
  83.     }
  84. }
Advertisement
Add Comment
Please, Sign In to add comment