{ >> There are advantages to linked lists, but I don't see ease of use as >> one of them. What could be easier to use than a TCollection? > An array. I still can't figure out how to use TCollections. Try this out. No TV, just a collection of stuff with a wee bit of streams.... } Program CollectingStuff; Uses Objects; Type Stuff = byte; StuffPtr = ^Stuff; StuffCollection = Object(TCollection) procedure FreeItem(Item:Pointer); virtual; procedure PutItem(var S:TStream;Item:Pointer); virtual; Function GetItem(var S:TStream):Pointer; virtual; end; StuffCollectionPtr = ^StuffCollection; Const RStuffCollection : TStreamRec = (ObjType : $424B; VMTLink : Ofs(TypeOf(StuffCollection)^); Load : @StuffCollection.Load; Store : @StuffCollection.Store); Var StuffArray : StuffCollectionPtr; procedure StuffCollection.FreeItem(Item:Pointer); begin dispose(StuffPtr(Item)); end; procedure StuffCollection.PutItem(var S:TStream;Item:Pointer); begin S.Write(StuffPtr(Item)^,SizeOf(Stuff)); end; Function StuffCollection.GetItem(var S:TStream):Pointer; var p:StuffPtr; Begin new(p); S.Read(p^,SizeOf(Stuff)); GetItem := p; End; Function SayWhat:Char; var s:String; Begin Writeln; if StuffArray <> Nil then Writeln('Current Array has ',StuffArray^.Count,' elements'); Writeln('[1] add stuff [2] remove stuff ', '[3] load stuff [4] store stuff '); Writeln('[5] view stuff [6] view all stuff ', '[7] match stuff (anything else exits))'); Readln(s); if s <> '' then SayWhat := s[1] else SayWhat := #0; End; Procedure AddToStuff; var sp:StuffPtr; b:byte; Begin if StuffArray = Nil then New(StuffArray,init(1,1)); repeat write('enter a byte : '); Readln(b); until ioresult = 0; new(sp); sp^ := b; StuffArray^.insert(sp); End; Procedure DelFromStuff; var w:word; Begin if (StuffArray = nil) or (StuffArray^.count = 0) then exit; repeat write('enter element number to delete : '); readln(w); until (ioresult = 0) and (w < StuffArray^.count); StuffArray^.AtFree(w); End; Procedure NewStuff; var s:string; f:PDosStream; Begin write('Enter the stuff''s file name : '); readln(s); new(f,init(s,StOpenRead)); if f^.status = StOk then begin if StuffArray <> nil then dispose(StuffArray,done); new(StuffArray,load(f^)); end; dispose(f,done); End; Procedure SaveStuff; var s:string; f:PDosStream; Begin write('Enter the stuff''s file name : '); readln(s); new(f,init(s,StCreate)); if f^.status = StOk then begin if StuffArray <> nil then StuffArray^.store(f^); end; dispose(f,done); End; Procedure ShowStuff; var w:word; Begin if (StuffArray = nil) or (StuffArray^.count = 0) then exit; repeat write('enter element number to view : '); readln(w); until (ioresult = 0) and (w < StuffArray^.count); writeln('Element # ',w,' = ',byte(StuffArray^.at(w)^)); End; Procedure AllStuff; Procedure ShowEm(p:StuffPtr); far; begin writeln('Stuff Element = [',byte(p^),']'); end; Begin if (StuffArray <> Nil) and (StuffArray^.count > 0) then StuffArray^.ForEach(@ShowEm); End; Procedure MatchStuff; var b:byte; p:StuffPtr; Function Matches(pb:StuffPtr):boolean; far; Begin Matches := pb^ = b; End; Begin if (StuffArray = Nil) or (StuffArray^.count = 0) then exit; repeat write('enter a byte to match : '); readln(b); until ioresult = 0; p := StuffArray^.FirstThat(@Matches); if p <> nil then writeln('Element ',StuffArray^.indexof(p), ' matches [',byte(p^),']') else writeln('no matches'); End; Procedure DoStuff; var stop:boolean; Begin stop := false; While not stop do Case SayWhat of '1' : AddToStuff; '2' : DelFromStuff; '3' : NewStuff; '4' : SaveStuff; '5' : ShowStuff; '6' : AllStuff; '7' : MatchStuff; else stop := true; end; End; var m:longint; begin m := memavail; registerType(RStuffCollection); StuffArray := Nil; DoStuff; if StuffArray <> Nil then Dispose(StuffArray,Done); if m <> memavail then writeln('heap ''a trouble'); end.