Seite 1 von 2

CopyStructure und LinkedLists

Verfasst: 25.05.2011 11:12
von delikanli_19_82
hallo leute,

ich habe hier eine konzeptfrage. wenn man jetzt mit pb ein interface-objekt bastelt, so muss ja seine gesamtgröße eindeutig sein. arrays können ja nicht direkt in so ein interface untergebracht werden. kann man dieses problem mit hilfe des copystructure-befehls lösen? und falls ja, wäre das ein guter ausweg, oder doch eher nicht zu empfehlen, da ja die gesamte struktur im speicher kopiert wird. die alte könnte man ja dann mit clearstructure löschen.

falls das nicht geht, dann eine andere frage. gibt es irgendeinen vernünftigen weg, interface-objekte dazu zu bringen, intern arrays aufzunehmen und zu verwalten.

im moment habe ich das problem dadurch umgangen, das ich globale struktur-variablen mit entsprechenden linkedlists und einem id versehen habe. wenn ein objekt-instanz geladen wird, so wird im konstruktur eine interne id-nummer erzeugt und in der globalen struktur-variable ein neuer abschnitt angelegt und dort ebenfalls die id eingetragen. immer wenn ich mit dem instanz-x arbeite, springt dessen methode sicherheitshalber jedesmal per foreach, innerhalb dieser globalen linkedlist an die richtige stelle und erst dann werden die daten ausgewertet bzw. manipuliert.

mfg

kurt

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 11:41
von NicTheQuick
Redest du von statischen Arrays oder von dynamischen Arrays? Die dynamischen Arrays kannst du doch ganz einfach in eine Structure einbauen, vorausgesetzt du hast ein aktuelles PureBasic.
Mach lieber mal einen kleinen Beispielcode, an dem wir das Problem genau verstehen können.

Danke! :)

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 12:00
von delikanli_19_82
der nachfolgende code funktioniert nicht, soll aber sinnesgemäß das wiederspiegeln, was ich mir vorstelle, wie ich es ungefähr haben will:

Code: Alles auswählen


; um bestimmte aufgabenbereiche eines objekts zu gruppieren, bastelle ich mehrere strukturen, die die erwünschten
; bereiche zusammenfassen.

; position und volumn des objekts
Structure objektname_p_sz
 x.l : y.l : w.l : h.l
EndStructure

; hier werden beispielsweise die daten zu einem Abschnitt gesammelt ( dieses beispiel ist fiktiv und soll eine komplexe array-struktur demonstrieren )
Structure objektname_con_ety
 List txt.s()
 List key.s()
 List nbr.l()
EndStructure

; hier werden beispielsweise die daten gesammelt (dynamisch natürlich)
Structure objektname_con
 list value.objektname_con_ety()
EndStructure

; Das Interface
Interface objektname
 methode_a()
 methode_n()
EndInterface

; Die Body-Struktur
Structure objektname_body
 Tbl.l
 Met.l[SizeOf(objektname)/4]
 psz.objektname_p_sz
 ; HIER DAS WAS ICH EIGENTLICH MÖCHTE, EINE STRUKTUR
 ; DIE EINEN DYNAMISCHEN ARRAY (und unter umständen eben
 ; weitere Subarray ) ENTHÄLT.
 con.objektname_con
EndStructure

...

Ich würde gerne eine solche oder ähnliche lösung haben, so das ich arrays in objekte integrieren kann, so das jedes
objekt seine eigene kopie der für ihn vorgesehenen linkedlists hat und damit arbeitet.

mfg

kurt

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 13:18
von delikanli_19_82
hat sich erledigt. habe eine lösung gefunden :-)

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 13:22
von Deluxe0321

Code: Alles auswählen

Interface __interface
  SayHello(Text.s)
  AddListElements(Count.i)
  AddArrayElements(Count.i)
  GetListSuff()
  GetArrayStuff()
  GetListElement()
  SetListElement(Element.i)
  GetArrayElement()
  SetArrayElement(Element.i)
  FreeAll()
EndInterface

Structure __listStruc
  A.i
  B.i
  C.i
EndStructure

Structure __arrayStruc
  Text.s
  int.i
EndStructure

Structure __interfaceStruc
  ___procs.i
  __MyListElement.i
  __MyArrayElement.i
  List MyList.__listStruc()
  Array MyArray.__arrayStruc(0)
EndStructure

Procedure _SayHello(*this.__interfaceStruc,Text.s)
  If Text.s
    MessageRequester("Hello",Text.s)
  EndIf
EndProcedure

Procedure _AddListElements(*this.__interfaceStruc,Count.i)
  If Count.i > 0
    For a=0 To Count.i
      AddElement(*this\MyList())
        *this\MyList()\A.i = Random(9999)
        *this\MyList()\B.i = Random(9999)
        *this\MyList()\C.i = Random(9999)
    Next
    ProcedureReturn Count.i
  EndIf
  ProcedureReturn -1
EndProcedure

Procedure _AddArrayElements(*this.__interfaceStruc,Count.i)
  If Count.i > 0
    ReDim *this\MyArray(Count.i)
    For a=0 To Count.i
        For b=0 To Count.i 
          *this\MyArray(a)\Text.s + Chr(65+Random(30))
        Next
        *this\MyArray(a)\int.i = Random(9999)
    Next
    ProcedureReturn Count.i
  EndIf
  ProcedureReturn -1
EndProcedure

Procedure _GetListSuff(*this.__interfaceStruc)
  Static *MyListStatic.__listStruc
  If ListSize(*this\MyList())
    ResetList(*this\MyList())
    SelectElement(*this\MyList(),*this\__MyListElement.i)
    *MyListStatic = *this\MyList()
    ProcedureReturn *MyListStatic
  EndIf
EndProcedure

Procedure _GetArrayStuff(*this.__interfaceStruc)
  Static *MyArrayStatic.__arrayStruc  
  If ArraySize(*this\MyArray())
    *MyArrayStatic = *this\MyArray(*this\__MyArrayElement.i)
    ProcedureReturn *MyArrayStatic
  EndIf
EndProcedure

Procedure _GetListElement(*this.__interfaceStruc)
  ProcedureReturn *this\__MyListElement.i
EndProcedure  

Procedure _SetListElement(*this.__interfaceStruc,Element.i)
  If Element.i > -1 And Element.i < ListSize(*this\MyList())
    *this\__MyListElement.i = Element.i
    ProcedureReturn #True  
  EndIf
EndProcedure  

Procedure _GetArrayElement(*this.__interfaceStruc)
  ProcedureReturn *this\__MyArrayElement.i
EndProcedure  

Procedure _SetArrayElement(*this.__interfaceStruc,Element.i)
  If Element.i > -1 And Element.i < ArraySize(*this\MyArray())
    *this\__MyArrayElement.i = Element.i
    ProcedureReturn #True  
  EndIf
EndProcedure

Procedure _FreeAll(*this.__interfaceStruc)
  If ListSize(*this\MyList())
    ClearList(*this\MyList())  
  EndIf
  
  If ArraySize(*this\MyArray())
    ReDim *this\MyArray(0)  
  EndIf
EndProcedure

Procedure NewMyInterface()
   Protected *this.__interfaceStruc
   
   *this = AllocateMemory(SizeOf(__interfaceStruc))
   If *this
     InitializeStructure(*this, __interfaceStruc)
      *this\__MyArrayElement = -1
      *this\__MyListElement  = -1
      *this\___procs.i = ?_interface_procs_
   EndIf
   
   ProcedureReturn *this  
EndProcedure

DataSection
  _interface_procs_:
  Data.i @_SayHello()
  Data.i @_AddListElements()
  Data.i @_AddArrayElements()
  Data.i @_GetListSuff()
  Data.i @_GetArrayStuff()
  Data.i @_GetListElement()
  Data.i @_SetListElement()
  Data.i @_GetArrayElement()
  Data.i @_SetArrayElement()
  Data.i @_FreeAll()
EndDataSection

;Create 3 "Structured Interfaces"
NewList *this.__interface() 
For a=0 To 3
  AddElement(*this())
  *this() = NewMyInterface()
Next

;We want one element for now
SelectElement(*this(),1)

*myList.__listStruc
*myArray.__arrayStruc

*this()\SayHello("I like Turtels!")

;generate some Elements
*this()\AddArrayElements(100)
*this()\AddListElements(100)


For a=0 To 3
  Debug a
  ;set the Element
  *this()\SetListElement(Random(100))
  
  ;get the stuff
  *myList = *this()\GetListSuff()
  Debug *myList\A.i
  Debug *myList\B.i
  Debug *myList\C.i
  Debug ""
Next

;set the Element
For a=0 To 3
  *this()\SetArrayElement(Random(100))
  
  ;get the stuff
  *myArray = *this()\GetArrayStuff()
  Debug *myArray\int.i
  Debug *myArray\Text.s
  Debug ""
Next

*this()\FreeAll()

KP, ob das dein Problem löst, ich verstehe dich nicht ganz. ;)
Intern kannst du erstellen, kopieren, löschen wie du lustig bist. Trotzdem musst du Angeben mit was gearbeitet werden soll.
Wenn du für Jedes Element deiner "Struktur" ein eigenes Inferface willst, ist das auch kein wirkliches Thema. Einfach erstellen.

Gruß Deluxe0321
Edit: Zu langsam :D Gut das du eine Lösung für dich gefunden hast.

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 14:01
von bobobo
aber schlecht dass die hier nicht gepostet worden ist :evil:

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 14:56
von delikanli_19_82
ich habe hier eine lösung gebastelt. bin damit aber nicht ganz zu frieden. eigentlich möchte ich die
struktur mit der linkedlist nicht global deklarieren, sondern in den objekt hineinpacken, so dass es von außen
nicht mehr zugänglich ist und nicht manipuliert werden kann.

Code: Alles auswählen

Structure capi_array_string_struct
  List lst.s()
EndStructure

Global NewList capi_array_string_data.capi_array_string_struct()
Global capi_array_string_pointer.l = 0

Interface capi_array_string
  Add( value.s )
  Index.l( value.l = -1 )
  Count.l()
  Delete( value.l = 0 )
  Value.s( value.l )
  Clear()
EndInterface

Structure capi_array_string_body
  Tbl.l
  Met.l[SizeOf(capi_array_string)/4]
  cnt.l
  ptr.l
  *lst.capi_array_string_struct
EndStructure

Procedure capi_array_string__Add( *this.capi_array_string_body, value.s )
  AddElement( *this\lst\lst() )
  *this\lst\lst() = value
  *this\cnt + 1
EndProcedure

Procedure.l capi_array_string__Index( *this.capi_array_string_body, value.l = -1 )
  If value >= 0 And value < *this\cnt
    SelectElement( *this\lst\lst(), value )
  EndIf
EndProcedure

Procedure.l capi_array_string__Count( *this.capi_array_string_body )
  ProcedureReturn *this\cnt
EndProcedure

Procedure.l capi_array_string__Delete( *this.capi_array_string_body, value.l = 0 )
  If value >= 0 And value < *this\cnt
    DeleteElement( *this\lst\lst(), value )
  EndIf
EndProcedure

Procedure.s capi_array_string__Value( *this.capi_array_string_body, value.l )
  If value >= 0 And value < *this\cnt
    SelectElement( *this\lst\lst(), value )
    ; ***
    ProcedureReturn *this\lst\lst()
  Else
    ProcedureReturn ""
  EndIf
EndProcedure

Procedure capi_array_string__Clear( *this.capi_array_string_body )
  ClearList( *this\lst\lst() )
  ; ***
  *this\cnt = 0
EndProcedure

Procedure capi_array_string ()
  *obj.capi_array_string_body = AllocateMemory(SizeOf(capi_array_string_body))
  If *obj = 0: ProcedureReturn 0 : EndIf ; Memory allocation failed
  *obj\Tbl = *obj + OffsetOf(capi_array_string_body\Met)
  ; ***
  *obj\cnt = 0
  ; ***
  AddElement( capi_array_string_data() )
  ; ***
  *obj\lst = capi_array_string_data()
  ; ***
  capi_array_string_pointer + 1
  ; ***
  *obj\Met[0] = @capi_array_string__Add()
  *obj\Met[1] = @capi_array_string__Index()
  *obj\Met[2] = @capi_array_string__Count()
  *obj\Met[3] = @capi_array_string__Delete()
  *obj\Met[4] = @capi_array_string__Value()
  *obj\Met[5] = @capi_array_string__Clear()
  ; ***
  ProcedureReturn *obj
EndProcedure

test.capi_array_string = capi_array_string()

test\Add( "Hallo" )
test\Add( "Welt" )
test\Add( "Ola" )
test\Add( "Ninja" )

Debug "TEST"
For x = 0 To test\Count() -1
  Debug test\Value(x)  
Next
Debug ""

zwei.capi_array_string = capi_array_string()

zwei\Add( "abc" )
zwei\Add( "def" )

Debug "ZWEI"
For x = 0 To zwei\Count() -1
  Debug zwei\Value(x)  
Next
ich habe versucht mit einer statischen strukturdeklaration innerhabl des constructors das problem zu lösen.
der hat aber den nachteil, das jede instanz, ja logischerweise, die selbe speicherstelle als interne liste
übernehmen. und das macht ja keinen sinn.

weiß jemand einen Rat?

mfg

kurt

Re: CopyStructure und LinkedLists

Verfasst: 25.05.2011 21:41
von NicTheQuick
Siehe Deluxe0321.

Re: CopyStructure und LinkedLists

Verfasst: 26.05.2011 04:04
von delikanli_19_82
hier eine endgültige version für strings. dieser funktioniert jetzt perfekt. nochmals danke an alle beteiligten. habe nun daraus
noch varianten für long, integer, byte, float, double, word und unicode erstellt.

Code: Alles auswählen


              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Class Interface
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Interface capi_array_string
                Add( value.s )
                Index.l( value.l = -1 )
                Count.l()
                Delete( value.l = 0 )
                ; Das {...} dient als Default, um damit einen ProcedureReturn, statt Manipulation zu bewirken
                Value.s( index.l, value.s = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}" )
                Clear()
                Sort( nocase.b = #False, increment.b = #True )
                Find.b( value.s, nocase.b = #False )
                Where.l( value.s, nocase.b = #False )
                Min.s()
                Max.s()
                Filter( value.s, nocase.b = #False )
              EndInterface
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Class Body Structure
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Structure capi_array_string_body
                Met.i
                cnt.l
                List lst.s()
              EndStructure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Add value
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure capi_array_string_Add( *this.capi_array_string_body, value.s )
                If *this\cnt > 0
                  LastElement( *this\lst() )
                EndIf
                ; ***
                AddElement( *this\lst() )
                ; ***
                *this\lst() = value
                ; ***
                *this\cnt + 1
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return or set index
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.l capi_array_string_Index( *this.capi_array_string_body, index.l = -1 )
                If index = -1
                  ProcedureReturn ListIndex( *this\lst() )
                ElseIf index >= 0 And index < *this\cnt
                  SelectElement( *this\lst(), index )
                EndIf
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return count of entries
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.l capi_array_string_Count( *this.capi_array_string_body )
                ProcedureReturn *this\cnt
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Delete an entry
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.l capi_array_string_Delete( *this.capi_array_string_body, index.l = 0 )
                If index >= 0 And index < *this\cnt
                  SelectElement( *this\lst(), index )
                  ; ***
                  DeleteElement( *this\lst() )
                  ; ***
                  *this\cnt - 1
                  ; ***
                  If *this\cnt > 0
                    LastElement( *this\lst() )
                  EndIf
                EndIf
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return or modify the value
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.s capi_array_string_Value( *this.capi_array_string_body, index.l, value.s = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}" )
                If index >= 0 And index < *this\cnt
                  SelectElement( *this\lst(), index )
                  ; ***
                  If value = "{ABCDE-EFC32-32321-0323EC-32DEC-123EF}"
                    ProcedureReturn *this\lst()
                  Else
                    *this\lst() = value
                  EndIf
                Else
                  ProcedureReturn ""
                EndIf
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Clear array
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure capi_array_string_Clear( *this.capi_array_string_body )
                If *this\cnt > 0
                  ClearList( *this\lst() )
                  ; ***
                  *this\cnt = 0
                EndIf
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Sort array
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure capi_array_string_Sort(  *this.capi_array_string_body, nocase.b = #False, increment.b = #True )
              
                If *this\cnt > 0
                  
                  If nocase = #False
                    
                    If increment = #True
                      
                      SortList( *this\lst(), #PB_Sort_Ascending | #PB_Sort_NoCase )
                      
                    Else
                      
                      SortList( *this\lst(), #PB_Sort_Descending | #PB_Sort_NoCase )
                      
                    EndIf
                    
                  Else
              
                    If increment = #True
                      
                      SortList( *this\lst(), #PB_Sort_Ascending )
                      
                    Else
                      
                      SortList( *this\lst(), #PB_Sort_Descending )
                      
                    EndIf
              
                  EndIf
              
                  LastElement( *this\lst() )
              
                EndIf
                
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Find a value. If found, return #true, otherwise #false.
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.b capi_array_string_Find(  *this.capi_array_string_body, value.s, nocase.b = #False )
                
                Define bool.b = #False, v.s
                
                If *this\cnt > 0
                  
                  ForEach *this\lst()
                    
                    v = *this\lst()
                    
                    If v = value And nocase = #False
                      
                      bool = #True
                      
                      Break
                      
                    ElseIf v = value And nocase = #True
                      
                      bool = #True
                      
                      Break
                      
                    ElseIf LCase(v) = LCase(value) And nocase = #True        
                      
                      bool = #True
                      
                      Break
              
                    EndIf
                    
                  Next
                  
                  LastElement( *this\lst() )
                  
                EndIf
                
                ProcedureReturn bool
                
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return the index of a found value, otherwise -1.
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.l capi_array_string_Where(  *this.capi_array_string_body, value.s, nocase.b = #False )
                
                Define pos.l = -1, v.s
                
                If *this\cnt > 0
                  
                  ForEach *this\lst()
                    
                    v = *this\lst()
                    
                    pos + 1
                    
                    If v = value And nocase = #False
                      
                      Break
                      
                    ElseIf v = value And nocase = #True
                      
                      Break
                      
                    ElseIf LCase(v) = LCase(value) And nocase = #True        
                      
                      Break
              
                    EndIf
                    
                  Next
                  
                  LastElement( *this\lst() )
                  
                EndIf
                
                ProcedureReturn pos
                
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return the smallest value
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.s capi_array_string_Min( *this.capi_array_string_body )
                
                Define v.s, t.s, c.l = 32000
                
                If *this\cnt > 0
                  
                  ForEach *this\lst()
                    
                    v = *this\lst()
                    
                    If Len(v) < c : c = Len(v) : t = v : EndIf
                    
                  Next
                  
                  LastElement( *this\lst() )
                  
                EndIf
                
                ProcedureReturn t
                
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Return the largest value
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure.s capi_array_string_Max( *this.capi_array_string_body )
                
                Define v.s, t.s, c.l = 0
                
                If *this\cnt > 0
                  
                  ForEach *this\lst()
                    
                    v = *this\lst()
                    
                    If Len(v) > c : c = Len(v) : t = v : EndIf
                    
                  Next
                  
                  LastElement( *this\lst() )
                  
                EndIf
                
                ProcedureReturn t
                
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Filter values from the list
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure capi_array_string_Filter(  *this.capi_array_string_body, value.s, nocase.b = #False )
              
                Define v.s
              
                If *this\cnt > 0
              
                  ForEach *this\lst()
              
                    v = *this\lst()
              
                    If v = value And nocase = #False
              
                      DeleteElement( *this\lst() ) : *this\cnt - 1
              
                    ElseIf v = value And nocase = #True
              
                      DeleteElement( *this\lst() ) : *this\cnt - 1
              
                    ElseIf LCase(v) = LCase(value) And nocase = #True        
              
                      DeleteElement( *this\lst() ) : *this\cnt - 1
              
                    EndIf
              
                  Next
              
                  If *this\cnt > 0 : LastElement( *this\lst() ) : EndIf
              
                EndIf

              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Class Construtor
              ;
              ; ------------------------------------------------------------------------------------------- ;

              Procedure capi_array_string()
              
                 Protected *this.capi_array_string_body
              
                 *this = AllocateMemory(SizeOf(capi_array_string_body))
                 If *this
                   InitializeStructure(*this, capi_array_string_body)
                    *this\cnt = 0
                    *this\Met.i = ?_capi_array_string_procs_
                 EndIf
              
                 ProcedureReturn *this  
              
              EndProcedure
              
              ; ------------------------------------------------------------------------------------------- ;
              ;
              ;   Class Methods
              ;
              ; ------------------------------------------------------------------------------------------- ;

              DataSection
                _capi_array_string_procs_:
                Data.i @capi_array_string_Add()
                Data.i @capi_array_string_Index()
                Data.i @capi_array_string_Count()
                Data.i @capi_array_string_Delete()
                Data.i @capi_array_string_Value()
                Data.i @capi_array_string_Clear()
                Data.i @capi_array_string_Sort()
                Data.i @capi_array_string_Find()
                Data.i @capi_array_string_Where()
                Data.i @capi_array_string_Min()
                Data.i @capi_array_string_Max()
                Data.i @capi_array_string_Filter()
              EndDataSection

und hier ein test:

Code: Alles auswählen


   test.capi_array_string = capi_array_string()

   test\Add( "Aachen" )
   test\Add( "Köln" )
   test\Add( "Düsseldorf" )
   test\Add( "Münster" )

   For x = 0 to test\Count() - 1
     Debug Test\Value(x)
   Next

   test\Sort( #True, #False )

   Debug ""

   For x = 0 to test\Count() - 1
     Debug Test\Value(x)
   Next

   Debug ""

   Debug test\Min()
   Debug test\Max()

   Debug test\Count()

   test\Clear()

   Debug ""

   Debug "Tada... :-)"


Re: CopyStructure und LinkedLists

Verfasst: 26.05.2011 10:52
von NicTheQuick
Min und Max könntest du optimieren, indem du die beiden Werte schon beim Hinzufügen (add()) aktualisierst und beim Abfragen einfach nur zurück gibst.
Desweiteren finde ich deine Definition von Min und Max für Strings merkwürdig. Ich verstehe darunter zumindest nicht die String-Länge.