1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27public
  28class LinkedList<E> {
  29
  30  
  31  
  32  
  33  
  34  
  35
  36  protected
  37  E info;
  38
  39  protected
  40  LinkedList<E> next;
  41
  42  
  43  
  44  
  45  
  46  
  47
  48  protected
  49  LinkedList(E info, LinkedList<E> next)
  50  {
  51    this.info = info;
  52    this.next = next;
  53  }
  54
  55  
  56  
  57  
  58  
  59  
  60  
  61  
  62
  63  public static
  64  <E> LinkedList<E> mkEmptyList()
  65  {
  66    return
  67      new LinkedList<E>(null, null);
  68  }
  69
  70  
  71  
  72  
  73  
  74
  75  public static
  76  <E> LinkedList<E> mkOne(E info)
  77  {
  78    LinkedList<E> res = mkEmptyList();
  79    return
  80      res.cons(info);
  81  }
  82
  83  
  84
  85  public
  86  LinkedList<E> cons(E info)
  87  {
  88    return 
  89      new LinkedList<E>(info, this);
  90  }
  91
  92  
  93
  94  public
  95  boolean isEmpty()
  96  {
  97    return
  98      next == null;
  99  }
 100
 101  
 102
 103  public
 104  E hd()
 105    throws IndexOutOfBoundsException
 106  {
 107    if ( isEmpty() )
 108      throw
 109        new IndexOutOfBoundsException("hd of empty list");
 110
 111    return
 112      info;
 113  }
 114
 115  
 116
 117  public
 118  LinkedList<E> tl()
 119    throws IndexOutOfBoundsException
 120  {
 121    if ( isEmpty() )
 122      throw
 123        new IndexOutOfBoundsException("tl of empty list");
 124
 125    return
 126      next;
 127  }
 128
 129  
 130
 131  public
 132  int len()
 133  {
 134    return
 135      isEmpty()
 136      ? 0
 137      : 1 + next.len();
 138  }
 139
 140  
 141
 142  public
 143  E at(int i)
 144    throws IndexOutOfBoundsException
 145  {
 146    if ( i < 0 || isEmpty() )
 147      throw
 148        new IndexOutOfBoundsException("illegal index into linked list");
 149
 150    return
 151      ( i == 0 )
 152      ? hd()
 153      : next.at(i - 1);
 154  }
 155
 156  
 157
 158  public
 159  boolean isIn(E o)
 160  {
 161    return
 162      ! isEmpty()
 163      &&
 164      ( info.equals(o)
 165        ||
 166        next.isIn(o) );
 167  }
 168
 169  
 170
 171  
 172
 173
 174
 175
 176  public
 177  LinkedList<E> insert(E o)
 178  {
 179    if ( isIn(o) )
 180      return
 181        this;
 182    
 183    return
 184      cons(o);
 185  }
 186
 187  
 188
 189  
 190
 191
 192
 193
 194  public
 195  LinkedList<E> remove(E o)
 196  {
 197    if ( isEmpty() )
 198      return
 199        this;
 200
 201    if ( info.equals(o) )
 202      return
 203        next;
 204
 205    next = next.remove(o);
 206    
 207    
 208
 209    return
 210      this;
 211  }
 212
 213  
 214
 215  public
 216  LinkedList<E> concat(LinkedList<E> l2)
 217  {
 218    if ( isEmpty() )
 219      return
 220        l2;
 221
 222    if ( next.isEmpty() ) {
 223      next = l2;
 224    } else {
 225      next = next.concat(l2);
 226    }
 227
 228    return
 229      this;
 230  }
 231
 232  
 233
 234  public
 235  LinkedList<E> append(E o)
 236  {
 237    return
 238      concat(mkOne(o));
 239  }
 240
 241  
 242
 243  public
 244  String toString()
 245  {
 246    if ( isEmpty() )
 247      return
 248        "[]";
 249
 250    return
 251      "[" + info.toString() + next.toString0();
 252
 253    
 254  }
 255
 256  private
 257  String toString0()
 258  {
 259    String s = "";
 260    if ( isEmpty() )
 261      return
 262        "]";
 263
 264    return
 265      "," + info.toString() + next.toString0();
 266  }
 267
 268  
 269  
 270
 271  public
 272  <Result> Result forall(Accumulate <E, Result> ac)
 273  {
 274    LinkedList<E> l1 = this;
 275
 276    while ( ! l1.isEmpty() ) {
 277      ac.process(l1.info);
 278      l1 = l1.next;
 279    }
 280
 281    return
 282      ac.getResult();
 283  }
 284
 285  
 286  
 287
 288  public
 289  int len1()
 290  {
 291    
 292    return
 293      forall(new NoOfElements<E>());
 294  }
 295
 296  
 297  
 298
 299  public
 300  String toString1()
 301  {
 302    return
 303      forall(new ToString <E>("[", ",", "]"));
 304  }
 305
 306  
 307  
 308  
 309  
 310
 311  
 312  
 313  
 314
 315  public
 316  int len2()
 317  {
 318    return
 319      forall(new LocalNoOfElements <E> ());
 320  }
 321
 322  
 323  
 324  
 325
 326  static
 327  private
 328  class LocalNoOfElements <E>
 329    extends Accumulate <E, Integer>
 330  {
 331    int result = 0;
 332
 333    public
 334    void process(E element)
 335      {
 336        ++result;
 337      }
 338
 339    public
 340    Integer getResult()
 341      {
 342        return
 343          result;
 344      }
 345  }
 346
 347  
 348
 349}