750 likes | 944 Views
Collections. Inheritance Polymorphism. Collection hierarchy. Collection () Bag ('contents') SequenceableCollection () ArrayedCollection () Interval (‘start’ ‘stop’ ‘end’) LinkedList ('firstLink' 'lastLink') Semaphore ('excessSignals')
E N D
Collections Inheritance Polymorphism
Collection hierarchy • Collection () • Bag ('contents') • SequenceableCollection () • ArrayedCollection () • Interval (‘start’ ‘stop’ ‘end’) • LinkedList ('firstLink' 'lastLink') • Semaphore ('excessSignals') • OrderedCollection ('firstIndex' 'lastIndex') • SortedCollection ('sortBlock') • Set ('tally') • Dictionary () • IdentitySet () Object-oriented Programming and Design - Johnson & Yoder - Day 3
ArrayedCollection hierarchy • ArrayedCollection () • Array () • String () • ByteString () • Symbol () • WideString () • Text ('string' 'runs') • RunArray ('runs' 'values' ’lastIndex' ’lastRun’ ‘lastOffest’) Object-oriented Programming and Design - Johnson & Yoder - Day 3
Collection as an Abstract Class • Collection has no instance variables. • Collection defines as subclassResponsibility • do: • add:, remove: (Changeable) • at:, at:put: (Sequenceable) Object-oriented Programming and Design - Johnson & Yoder - Day 3
Collection as an Abstract Class • Template methods defined in terms of do: • select:, collect:, inject:into:, detect:ifAbsent:, size Object-oriented Programming and Design - Johnson & Yoder - Day 3
Abstract Classes • Abstract class as template • most operations defined in terms of do: • improved program skeleton • Abstract class as type • All collections understand same protocol (do:, select:, collect, etc.) Object-oriented Programming and Design - Johnson & Yoder - Day 3
Abstract class as type • All collections understand same protocol • do: iterate • select: subcollection • collect: transformed collection • inject:into: reduce collection to value • includes: does receiver contain it? Object-oriented Programming and Design - Johnson & Yoder - Day 3
Finding an element • numbers do: [:each | each isOdd ifTrue: [^firstOdd := each]]. • … firstOdd ... • numbers do: [:each | each isOdd ifTrue: [firstOdd ifNil ifTrue: [firstOdd := each]]] • firstOdd := numbers detect: [:each | each isOdd] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Find an Element • detect: aBlock ifNone: exceptionBlock • "Evaluate aBlock with each of the receiver's elements as the argument. Answer the first element for which aBlock evaluates to true." • self do: [:each | (aBlock value: each) • ifTrue: [^each]]. • ^exceptionBlock value Object-oriented Programming and Design - Johnson & Yoder - Day 3
Transform a Collection • collect: aBlock • | newCollection | • newCollection := self species new. • self do: [:each | newCollection add: (aBlock value: each)]. • ^newCollection Object-oriented Programming and Design - Johnson & Yoder - Day 3
Nonuniform Collection Protocol • add: and remove: are defined by collections whose size can change---Set, OrderedCollection, Bag, etc. • ArrayedCollection and Interval do not implement add: and remove: • at: and at:put: are defined by SequenceableCollection and Dictionary, but not by Set or Bag. Object-oriented Programming and Design - Johnson & Yoder - Day 3
Collection Protocols • Collection do:, size, select:, collect:, inject:into:, includes: • ChangeableCollection add: addAll: remove: removeAll: • SequenceableCollection at: at:put first last , copyFrom:to: Object-oriented Programming and Design - Johnson & Yoder - Day 3
Collection Menagerie • Array, String • Seq. • Symbol • Seq., read-only, unique • OrderedCollection • Seq., Changeable., a sequence • Set, Bag Changeable Object-oriented Programming and Design - Johnson & Yoder - Day 3
Collection Menagerie • Dictionary • at: and at:put: with any object as key • Interval • Seq., numeric, read-only • RunArray • Seq., compact encoding Object-oriented Programming and Design - Johnson & Yoder - Day 3
SequenceableCollection Example • x := collection first. • collection do: [:each | x := x min: each] • x := collection inject: collection first into: [:result :each | result min: each] Object-oriented Programming and Design - Johnson & Yoder - Day 3
SequenceableCollection • = aCollection • self size = aCollection size ifFalse: [^false]. • 1 to: self size do: [:i | (self at: i) = (aCollection at: i) ifFalse: [^false]. • ^true Object-oriented Programming and Design - Johnson & Yoder - Day 3
Dictionary Example • employees • at: 'John Doe' put: 319426621; • at: 'Jane Smith' put: 321654321 • employees keys • employees values Object-oriented Programming and Design - Johnson & Yoder - Day 3
(continued) • employees do: [:ssNum | ... ] • employees keysAndValuesDo: [:key :value | • Transcript show: key; show: ' has number '; • show: (value printString); cr] Object-oriented Programming and Design - Johnson & Yoder - Day 3
OrderedCollection Instance variables: firstIndex, lastIndex A changeable sequenceable collection. Supports add:, remove:, at:, at:put: Object-oriented Programming and Design - Johnson & Yoder - Day 3
OrderedCollection • at: anInteger • anInteger isInteger ifFalse: [ ^...]. • (anInteger < 1 or: [anInteger + firstIndex - 1 > lastIndex]) • ifTrue: [^...] • ^ super at: anInteger + firstIndex - 1 Object-oriented Programming and Design - Johnson & Yoder - Day 3
OC::do: • do: aBlock • firstIndex to: lastIndex do: • [:index | aBlock value: (self basicAt: index)]. • size • ^ lastIndex - firstIndex + 1 Object-oriented Programming and Design - Johnson & Yoder - Day 3
OC::add: • add: newObject • "Include newObject as one of the receiver's elements. Answer newObject." • ^ self addLast: newObject Object-oriented Programming and Design - Johnson & Yoder - Day 3
OC::add: • addLast: newObject • "Add newObject to the end of the receiver. Answer newObject." • lastIndex = self basicSize ifTrue: [self makeRoomAtLast]. • lastIndex lastIndex + 1. • self basicAt: lastIndex put: newObject. • ^ newObject Object-oriented Programming and Design - Johnson & Yoder - Day 3
Using OrderedCollections • Suppose that list is an ordered collection. We want newList to be the reverse of list. • solution 1 • newList := OrderedCollection new. • list do: [:each | newList addFirst: each] Object-oriented Programming and Design - Johnson & Yoder - Day 3
(continued) • solution 2 • newList := OrderedCollection newWithSize: list size. • index := list size. • list do: [:each | newList at: index put: each. • index := index - 1] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Interval • Instance variables: start, stop, step • 1 to: 1000 • 1 to: 1000 by: 3 • 1 to: 1000 do: [:each | sum sum + each] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Interval • Number • to: stop • ^ Interval from: self to: stop by: 1 Object-oriented Programming and Design - Johnson & Yoder - Day 3
Interval do: • do: aBlock • | n end | • n := 0. • end := self size - 1. • [n <= end] • whileTrue: • [aBlock value: start + (step * n). • n := n + 1] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Interval at: and at:put: • at: anInteger • (anInteger >= 1 and: [anInteger <= self size]) • ifTrue: [^start + (step * (anInteger - 1))] • ifFalse: [^self subscriptBoundsError: anInteger] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Interval at:put: • at: anInteger put: anObject • "Provide an error notification that storing into an Interval is not allowed. " • self error: 'you can not store into an interval' Object-oriented Programming and Design - Johnson & Yoder - Day 3
Set 3 19 $x 11 'hi!' A hash table. nil means an unused entry. Instance variables: tally Object-oriented Programming and Design - Johnson & Yoder - Day 3
Hash • Sets and Dictionaries depend on the hash of their elements. • Each object has an integer hash value. • Some classes redefine hash. • Invariant: Equal (=) objects hash equally. Object-oriented Programming and Design - Johnson & Yoder - Day 3
Classic Set Bugs • Some classes redefine hash. • Invariant: Equal (=) objects hash equally. • Bug 1: redefine = but not hash for some class. • -- aSet add: x. • x = y • ifTrue: [(aSet includes: y) • ifFalse: [self error]] Object-oriented Programming and Design - Johnson & Yoder - Day 3
SequenceableCollection • = otherCollection • self == otherCollection ifTrue: [^ true]. • self species == otherCollection species • ifFalse: [^ false]. • ^ self hasEqualElements: otherCollection Object-oriented Programming and Design - Johnson & Yoder - Day 3
SequenceableCollection • hash • | hash | • hash := self species hash. • 1 to: self size • do: [:i | hash := (hash + (self at: i) hash) hashMultiply]. • ^hash Object-oriented Programming and Design - Johnson & Yoder - Day 3
Set bugs • Bug 2: Define = so it depends on state of the object. • Put object in set, then change its state, then try to find it! • Rule of thumb: only redefine = if object is immutable. Object-oriented Programming and Design - Johnson & Yoder - Day 3
Set do: • do: aBlock • tally == 0 ifTrue: [^self]. • 1 to: self basicSize do: • [:index | • | elem | • (elem := self basicAt: index) == nil ifFalse: [aBlock value: elem]] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Set includes: • includes: anObject • "Answer whether anObject is one of the receiver's elements." • ^(array at: (self findElementOrNil: anObject)) notNil Object-oriented Programming and Design - Johnson & Yoder - Day 3
Set • findElementOrNil: anObject • "Answer the index of a first slot containing either a nil (indicating an empty slot) or an element that matches the given object. Answer the index of that slot or zero. Fail if neither a match nor an empty slot is found.” • | index | • index := self scanFor: anObject. • index > 0 ifTrue: [^index]. • self error: 'There is no free space in this set!'. Object-oriented Programming and Design - Johnson & Yoder - Day 3
scanFor: anObject • | element start finish | • finish _ array size. • start _ (anObject hash \\ finish) + 1. • "Search from (hash mod size) to the end." • start to: finish do: • [:index | ((element _ array at: index) == nil or: [element = anObject]) • ifTrue: [^ index ]]. • "Search from 1 to where we started." • 1 to: start-1 do: • [:index | ((element _ array at: index) == nil or: [element = anObject]) • ifTrue: [^ index ]]. • ^ 0 "No match AND no empty slot" Object-oriented Programming and Design - Johnson & Yoder - Day 3
Classic Collection Bugs • add: returns argument • (aSet add: 3) add: 2 --- wrong • aSet add: 3; add: 2 --- right • How are these different? • Array with: 3 with: 17 with: -9 • #(3 17 -9) Object-oriented Programming and Design - Johnson & Yoder - Day 3
Conclusion • Collection is a typical class hierarchy • abstract classes on top • important interfaces, not completely regular • make assumptions (hash, =) about other classes Object-oriented Programming and Design - Johnson & Yoder - Day 3
Streams Stream protocol Object composition
Uses of Streams • External iterator • Parsing • Formatted output • Dataflow computing • File I/O Object-oriented Programming and Design - Johnson & Yoder - Day 3
ReadStream Protocol • ReadStream • next, atEnd • (do:, nextMatchFor:) • #next is valid if #atEnd is false. Object-oriented Programming and Design - Johnson & Yoder - Day 3
ReadStream • t := ReadStream on: ‘this is the input’. • [t atEnd] • whileFalse: • [t next = $p ifTrue: [^t]]] Object-oriented Programming and Design - Johnson & Yoder - Day 3
Iterator • Internal Iterator - do: • External Iterator - streams • Internal iterator is easier to use, but less powerful. • External iterators needed for simultaneous iteration. Object-oriented Programming and Design - Johnson & Yoder - Day 3
Iterator • “return true if streams equal” • [stream1 atEnd | stream2 atEnd] • whileFalse: • [stream1 next = stream2 next • ifFalse: [^false]]. • ^stream1 atEnd & stream2 atEnd Object-oriented Programming and Design - Johnson & Yoder - Day 3
Stream Protocol • WriteStream • nextPut: • (nextPutAll:, cr, tab, space) Object-oriented Programming and Design - Johnson & Yoder - Day 3
Component systems • Need standard interfaces • Interfaces should be simple • Component library • Easy to make new components • Complexity is in way components are arranged Object-oriented Programming and Design - Johnson & Yoder - Day 3