samples/effectivelist/src/org/apidesign/effectivelist/List.scala
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 31 Aug 2012 20:16:57 +0200
changeset 402 e25dbfce40e9
child 403 ebe08056c60c
permissions -rw-r--r--
Example demostrating how to use trait to provide effective implementation of linked list while keeping encapsulation
     1 package org.apidesign.effectivelist
     2 
     3 /** 
     4  * Implementation of add and remove efficient list. It has just one
     5  * restriction - its items need to carry additional information to help
     6  * the list to be effective. All items must extend trait {@link Listable}:
     7  * <pre>
     8  * <b>case class</b> Person(name : String) <b>extends</b> Listable[Person]
     9  * </pre>
    10  */
    11 final class List[T <: Listable[T]] {
    12   private var item : T = _
    13   private final var EMPTY : T = _
    14   
    15   final def get(index : Int) : T = {
    16     var pos : T = item;
    17     for (i <- 1 to index) {
    18       pos = pos.next;
    19       if (pos == item) {
    20         throw new IndexOutOfBoundsException()
    21       }
    22     }
    23     return pos
    24   }
    25   
    26   final def size() : Int = {
    27     if (item == EMPTY) {
    28       return 0
    29     }
    30     var size = 0
    31     var pos : T = item
    32     do {
    33       size = size + 1
    34       pos = pos.next
    35     } while (pos != item)
    36     return size
    37   }
    38   
    39   final def add(toAdd : T) : Boolean = {
    40     if (toAdd.prev != EMPTY) {
    41       return false
    42     }
    43     
    44     if (item == null) {
    45       item = toAdd
    46       toAdd.next = toAdd
    47       toAdd.prev = toAdd
    48       return true
    49     } else {
    50       toAdd.prev = item.prev
    51       item.prev.next = toAdd
    52       item.prev = toAdd
    53       toAdd.next = item
    54       return true
    55     }
    56   }
    57   final def remove(toRemove : T) : Boolean = {
    58     if (toRemove.prev == EMPTY) {
    59       return false
    60     } else {
    61       toRemove.prev.next = toRemove.next
    62       toRemove.next.prev = toRemove.prev;
    63       if (item.next == item) {
    64         item = EMPTY
    65       }
    66       if (item == toRemove) {
    67         item = toRemove.next
    68       }
    69       toRemove.next = EMPTY
    70       toRemove.prev = EMPTY
    71       return true
    72     }
    73   }
    74 }