Collection.st
changeset 1 a27a279701f8
child 2 6526dde5f3ac
equal deleted inserted replaced
0:aa2498ef6470 1:a27a279701f8
       
     1 "
       
     2  COPYRIGHT (c) 1989-93 by Claus Gittinger
       
     3               All Rights Reserved
       
     4 
       
     5  This software is furnished under a license and may be used
       
     6  only in accordance with the terms of that license and with the
       
     7  inclusion of the above copyright notice.   This software may not
       
     8  be provided or otherwise made available to, or used by, any
       
     9  other person.  No title to or ownership of the software is
       
    10  hereby transferred.
       
    11 "
       
    12 
       
    13 Object subclass:#Collection
       
    14        instanceVariableNames:''
       
    15        classVariableNames:''
       
    16        poolDictionaries:''
       
    17        category:'Collections-Abstract'
       
    18 !
       
    19 
       
    20 Collection comment:'
       
    21 
       
    22 COPYRIGHT (c) 1989-93 by Claus Gittinger
       
    23               All Rights Reserved
       
    24 
       
    25 Abstract superclass for all collections
       
    26 
       
    27 %W% %E%
       
    28 '!
       
    29 
       
    30 !Collection class methodsFor:'instance creation'!
       
    31 
       
    32 with:anObject
       
    33     "return a new Collection with one element:anObject"
       
    34 
       
    35     |newCollection|
       
    36 
       
    37     newCollection := self new.
       
    38     newCollection add:anObject.
       
    39     ^ newCollection
       
    40 !
       
    41 
       
    42 with:firstObject with:secondObject
       
    43     "return a new Collection with two elements:firstObject and secondObject"
       
    44 
       
    45     |newCollection|
       
    46 
       
    47     newCollection := self new.
       
    48     newCollection add:firstObject.
       
    49     newCollection add:secondObject.
       
    50     ^ newCollection
       
    51 !
       
    52 
       
    53 with:firstObject with:secondObject with:thirdObject
       
    54     "return a new Collection with three elements"
       
    55 
       
    56     |newCollection|
       
    57 
       
    58     newCollection := self new.
       
    59     newCollection add:firstObject.
       
    60     newCollection add:secondObject.
       
    61     newCollection add:thirdObject.
       
    62     ^ newCollection
       
    63 !
       
    64 
       
    65 with:firstObject with:secondObject with:thirdObject with:fourthObject
       
    66     "return a new Collection with four elements"
       
    67 
       
    68     |newCollection|
       
    69 
       
    70     newCollection := self new.
       
    71     newCollection add:firstObject.
       
    72     newCollection add:secondObject.
       
    73     newCollection add:thirdObject.
       
    74     newCollection add:fourthObject.
       
    75     ^ newCollection
       
    76 !
       
    77 
       
    78 new:size withAll:element
       
    79     "return a new COllection of size, where all elements are
       
    80      initialized to element"
       
    81 
       
    82     |newCollection|
       
    83 
       
    84     newCollection := self new:size.
       
    85     size timesRepeat:[newCollection add:element]
       
    86 !
       
    87 
       
    88 withAll:aCollection
       
    89     "return a new Collection with all elements taken from the argument,
       
    90      aCollection"
       
    91 
       
    92     |newCollection|
       
    93 
       
    94     newCollection := self new.
       
    95     newCollection addAll:aCollection.
       
    96     ^newCollection
       
    97 ! !
       
    98 
       
    99 !Collection methodsFor:'error handling'!
       
   100 
       
   101 errorNotFound
       
   102     "report an error that Object was not in the collection"
       
   103 
       
   104     self error:'Object is not in the Collection'
       
   105 !
       
   106 
       
   107 errorNotKeyed
       
   108     "report an error that keyed access methods are not allowed"
       
   109 
       
   110     self error:(self class name, 's do not respond to keyed accessing messages')
       
   111 ! !
       
   112 
       
   113 !Collection methodsFor:'accessing'!
       
   114 
       
   115 anElement
       
   116     "return any element from the collection"
       
   117 
       
   118     self do: [:each | ^ each].
       
   119     ^ nil
       
   120 ! !
       
   121 
       
   122 !Collection methodsFor:'adding & removing'!
       
   123 
       
   124 add:anObject
       
   125     "add the argument, anObject to the receiver"
       
   126 
       
   127     ^ self subclassResponsibility
       
   128 !
       
   129 
       
   130 addLast:anObject
       
   131     "add the argument, anObject to the receiver"
       
   132 
       
   133     ^ self add:anObject
       
   134 !
       
   135 
       
   136 addAll:aCollection
       
   137     "add all elements of the argument, aCollection to the receiver"
       
   138 
       
   139     aCollection do:[:element |
       
   140         self add:element
       
   141     ].
       
   142     ^ aCollection
       
   143 !
       
   144 
       
   145 remove:anObject ifAbsent:exceptionBlock
       
   146     "remove the argument, anObject from the receiver - if it was not
       
   147      in the collection returns the the value of the exceptionBlock"
       
   148 
       
   149     ^ self subclassResponsibility
       
   150 !
       
   151 
       
   152 remove:anObject
       
   153     "remove the argument, anObject from the receiver"
       
   154 
       
   155     self remove:anObject ifAbsent:[self errorNotFound]
       
   156 !
       
   157 
       
   158 removeAll:aCollection
       
   159     "remove all elements of the argument, aCollection from the receiver"
       
   160 
       
   161     aCollection do:[:element | self remove:element].
       
   162     ^ aCollection
       
   163 ! !
       
   164 
       
   165 !Collection methodsFor:'growing'!
       
   166 
       
   167 growSize
       
   168     "return a suitable size increment for growing"
       
   169 
       
   170     ^ self size max:2
       
   171 !
       
   172 
       
   173 grow
       
   174     "make the receiver larger"
       
   175 
       
   176     self grow:(self size + self growSize)
       
   177 !
       
   178 
       
   179 grow:howBig
       
   180     "change the receivers size"
       
   181 
       
   182     ^ self subclassResponsibility
       
   183 ! !
       
   184 
       
   185 !Collection methodsFor:'testing'!
       
   186 
       
   187 isEmpty
       
   188     "return true, if the receiver is empty"
       
   189 
       
   190     ^ self size == 0
       
   191 !
       
   192 
       
   193 includes:anElement
       
   194     "return true, if the argument, anObject is in the list"
       
   195 
       
   196     self do:[:element |
       
   197         (anElement = element) ifTrue:[^ true].
       
   198     ].
       
   199     ^ false
       
   200 !
       
   201 
       
   202 includesAll:aCollection
       
   203     "return true, if the the receiver includes all elements of
       
   204      the argument, aCollection; false if any is missing"
       
   205 
       
   206     aCollection do:[:element |
       
   207         (self includes:element) ifFalse:[^ false].
       
   208     ].
       
   209     ^ true
       
   210 !
       
   211 
       
   212 occurrencesOf:anElement
       
   213     "return the number of occurrences of the argument, anElement in
       
   214      the receiver"
       
   215 
       
   216     |count "<SmallInteger>" |
       
   217 
       
   218     count := 0.
       
   219     self do:[:element |
       
   220         (anElement = element) ifTrue:[
       
   221             count := count + 1
       
   222         ].
       
   223     ].
       
   224     ^ count
       
   225 !
       
   226 
       
   227 size
       
   228     "return the number of elements in the receiver"
       
   229 
       
   230     |count "<SmallInteger>" |
       
   231 
       
   232     count := 0.
       
   233     self do:[:element |
       
   234         count := count + 1
       
   235     ].
       
   236     ^ count
       
   237 ! !
       
   238 
       
   239 !Collection methodsFor:'enumerating'!
       
   240 
       
   241 do:aBlock
       
   242     "evaluate the argument, aBlock for each element"
       
   243 
       
   244     ^ self subclassResponsibility
       
   245 !
       
   246 
       
   247 collect:aBlock
       
   248     "for each element in the receiver, evaluate the argument, aBlock
       
   249      and return a new collection with the results"
       
   250 
       
   251     |newCollection|
       
   252 
       
   253     newCollection := self species new.
       
   254     self do:[:each | newCollection add:(aBlock value:each)].
       
   255     ^ newCollection
       
   256 !
       
   257 
       
   258 detect:aBlock
       
   259     "evaluate the argument, aBlock for each element in the receiver until
       
   260      the block returns true; in this case return the element which caused
       
   261      the true evaluation.
       
   262      If none of the evaluations return true, report an error"
       
   263 
       
   264     ^ self detect:aBlock ifNone:[self errorNotFound]
       
   265 !
       
   266 
       
   267 detect:aBlock ifNone:exceptionBlock
       
   268     "evaluate the argument, aBlock for each element in the receiver until
       
   269      the block returns true; in this case return the element which caused
       
   270      the true evaluation.
       
   271      If none of the evaluations returns true, return the result of the
       
   272      evaluation of the exceptionBlock"
       
   273 
       
   274     self do:[:each | 
       
   275         (aBlock value:each) ifTrue:[^ each].
       
   276     ].
       
   277     ^ exceptionBlock value
       
   278 !
       
   279 
       
   280 inject:thisValue into:binaryBlock
       
   281     |nextValue|
       
   282 
       
   283     nextValue := thisValue.
       
   284     self do: [:each | nextValue := binaryBlock value:nextValue value:each].
       
   285     ^ nextValue
       
   286 !
       
   287 
       
   288 reject:aBlock
       
   289     "return a new collection with all elements from the receiver, for which
       
   290      the argument aBlock evaluates to false"
       
   291 
       
   292     ^ self select:[:element | (aBlock value:element) == false]
       
   293 !
       
   294 
       
   295 select:aBlock
       
   296     "return a new collection with all elements from the receiver, for which
       
   297      the argument aBlock evaluates to true"
       
   298 
       
   299     |newCollection|
       
   300 
       
   301     newCollection := self species new.
       
   302     self do:[:each |
       
   303         (aBlock value:each) ifTrue:[newCollection add:each].
       
   304     ].
       
   305     ^ newCollection
       
   306 ! !
       
   307 
       
   308 !Collection methodsFor:'converting'!
       
   309 
       
   310 asArray
       
   311     "return a new Array with the collections elements"
       
   312 
       
   313     |anArray 
       
   314      index "<SmallInteger>" |
       
   315 
       
   316     anArray := Array new:(self size).
       
   317     index := 1.
       
   318     self do:[:each |
       
   319         anArray at:index put:each.
       
   320         index := index + 1
       
   321     ].
       
   322     ^ anArray
       
   323 !
       
   324 
       
   325 asByteArray
       
   326     "return a new ByteArray with the collections elements"
       
   327 
       
   328     |aByteArray 
       
   329      index "<SmallInteger>" |
       
   330 
       
   331     aByteArray := ByteArray new:(self size).
       
   332     index := 1.
       
   333     self do:[:each |
       
   334         aByteArray at:index put:each asInteger.
       
   335         index := index + 1
       
   336     ].
       
   337     ^ aByteArray
       
   338 !
       
   339 
       
   340 asString
       
   341     "return a String with the collections elements 
       
   342      (which must convertable to characters)"
       
   343 
       
   344     |aString 
       
   345      index "<SmallInteger>" |
       
   346 
       
   347     aString := String new:(self size).
       
   348     index := 1.
       
   349     self do:[:each |
       
   350         aString at:index put:each asCharacter.
       
   351         index := index + 1
       
   352     ].
       
   353     ^ aString
       
   354 !
       
   355 
       
   356 asText
       
   357     "return a new Text-object with the elements printstings"
       
   358 
       
   359     |aText
       
   360      index "<SmallInteger>" |
       
   361 
       
   362     aText := Text new:(self size).
       
   363     index := 1.
       
   364     self do:[:each |
       
   365         aText at:index put:(each printString).
       
   366         index := index + 1
       
   367     ].
       
   368     ^ aText
       
   369 !
       
   370 
       
   371 asBag
       
   372     "return a new Bag with the receiver collections elements"
       
   373 
       
   374     |aBag|
       
   375 
       
   376     aBag := Bag new.
       
   377     self do:[:each | aBag add:each].
       
   378     ^ aBag
       
   379 !
       
   380 
       
   381 asOrderedCollection
       
   382     "return a new OrderedCollection with the receiver collections elements"
       
   383 
       
   384     |anOrderedCollection|
       
   385 
       
   386     anOrderedCollection := OrderedCollection new:self size.
       
   387     self do:[:each | anOrderedCollection addLast:each].
       
   388     ^ anOrderedCollection
       
   389 !
       
   390 
       
   391 asSet
       
   392     "return a new Set with the receiver collections elements"
       
   393 
       
   394     |aSet|
       
   395 
       
   396     aSet := Set new: self size.
       
   397     self do:[:each | aSet add:each].
       
   398     ^ aSet
       
   399 !
       
   400 
       
   401 asSortedCollection
       
   402     "return a new SortedCollection with the receiver collections elements"
       
   403 
       
   404     |aSortedCollection|
       
   405 
       
   406     aSortedCollection := SortedCollection new:self size.
       
   407     aSortedCollection addAll:self.
       
   408     ^ aSortedCollection
       
   409 !
       
   410 
       
   411 asSortedCollection:sortBlock
       
   412     "return a new SortedCollection with the receiver collections elements,
       
   413      using sortBlock for comparing"
       
   414 
       
   415     |aSortedCollection|
       
   416 
       
   417     aSortedCollection := SortedCollection sortBlock:sortBlock.
       
   418     aSortedCollection addAll:self.
       
   419     ^ aSortedCollection
       
   420 ! !
       
   421 
       
   422 !Collection methodsFor:'printing & storing'!
       
   423 
       
   424 maxPrint
       
   425     ^ 5000
       
   426 !
       
   427 
       
   428 printString
       
   429     "return the printString of a big collection can take a long time
       
   430      due to long temporary strings - I use a buffer here collecting some
       
   431      elements to reduce the GC overhead ...
       
   432     "
       
   433 
       
   434     |thisString buffer count string noneYet total|
       
   435 
       
   436     string := (self class name) , '('.
       
   437     noneYet := true.
       
   438     buffer := ''.
       
   439     count := 0.
       
   440     total := 0.
       
   441     self do: [:element |
       
   442         thisString := element printString.
       
   443         noneYet ifTrue:[
       
   444             noneYet := false.
       
   445             buffer := buffer , thisString
       
   446         ] ifFalse:[
       
   447             buffer := buffer , (' ' , thisString)
       
   448         ].
       
   449         count := count + 1.
       
   450         (count == 20) ifTrue:[
       
   451             string := string , buffer.
       
   452             buffer := ''.
       
   453             count := 0
       
   454         ].
       
   455         total := total + 1.
       
   456         (total > 5000) ifTrue:[
       
   457             string := string , buffer , '... )'.
       
   458             ^string
       
   459         ]
       
   460     ].
       
   461     string := string , buffer , ')'.
       
   462     ^string
       
   463 !
       
   464 
       
   465 displayString
       
   466     "return the printString of a big collection can take a long time
       
   467      due to long temporary strings - I use a buffer here collecting some
       
   468      elements to reduce the GC overhead ...
       
   469     "
       
   470 
       
   471     |thisString buffer count string noneYet total|
       
   472 
       
   473     string := (self class name) , '('.
       
   474     noneYet := true.
       
   475     buffer := ''.
       
   476     count := 0.
       
   477     total := 0.
       
   478     self do: [:element |
       
   479         thisString := element displayString.
       
   480         noneYet ifTrue:[
       
   481             noneYet := false.
       
   482             buffer := buffer , thisString
       
   483         ] ifFalse:[
       
   484             buffer := buffer , (' ' , thisString)
       
   485         ].
       
   486         count := count + 1.
       
   487         (count == 20) ifTrue:[
       
   488             string := string , buffer.
       
   489             buffer := ''.
       
   490             count := 0
       
   491         ].
       
   492         total := total + 1.
       
   493         (total > 5000) ifTrue:[
       
   494             string := string , buffer , '... )'.
       
   495             ^string
       
   496         ]
       
   497     ].
       
   498     string := string , buffer , ')'.
       
   499     ^string
       
   500 !
       
   501 
       
   502 printOn:aStream
       
   503     |tooMany firstOne noMore|
       
   504 
       
   505     tooMany := aStream position + self maxPrint.
       
   506     aStream nextPutAll:self class name.
       
   507     aStream nextPut:$(.
       
   508     firstOne := true.
       
   509     noMore := false.
       
   510     self do:[:element |
       
   511         noMore ifFalse:[
       
   512             firstOne ifFalse:[
       
   513                 aStream nextPut:(Character space)
       
   514             ] ifTrue:[
       
   515                 firstOne := false
       
   516             ].
       
   517             (aStream position > tooMany) ifTrue:[
       
   518                 aStream nextPutAll:'...etc...)'.
       
   519                 noMore := true
       
   520             ] ifFalse:[
       
   521                 element printOn:aStream
       
   522             ]
       
   523         ].
       
   524     ].
       
   525     aStream nextPut:$)
       
   526 !
       
   527 
       
   528 storeOn:aStream
       
   529     "output a printed representation (which can be re-read)
       
   530      onto the argument aStream"
       
   531 
       
   532     |isEmpty|
       
   533 
       
   534     aStream nextPutAll:'(('.
       
   535     aStream nextPutAll:(self class name).
       
   536     aStream nextPutAll:' new)'.
       
   537     isEmpty := true.
       
   538     self do:[:element |
       
   539         aStream nextPutAll:' add: '.
       
   540         element storeOn:aStream.
       
   541         aStream nextPut:$;.
       
   542         isEmpty := false
       
   543     ].
       
   544     isEmpty ifFalse:[aStream nextPutAll:' yourself'].
       
   545     aStream nextPut:$)
       
   546 ! !