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