Sie sind auf Seite 1von 66

Map

7 January 2019 OSU CSE 1


Map
• The Map component family allows you to
manipulate mappings from keys (of any
type K) to values (of any type V)
– A Map variable holds a very simple “database”
of keys and their associated values
– Example: If you need to keep track of the
exam grade for each student, you might use a
Map<String,Integer> variable

7 January 2019 OSU CSE 2


Interfaces and Classes
Standard Iterable

extends extends

MapKernel

extends

Map
implements implements

Map1L Map3
Map2
7 January 2019 OSU CSE 3
Interfaces and Classes
Standard Iterable

extends extends
Standard has contracts
for three methods: MapKernel
clear
newInstance extends
transferFrom
Map
implements implements

Map1L Map3
Map2
7 January 2019 OSU CSE 4
Interfaces and Classes
Standard Iterable

extends extends

MapKernel
MapKernel has contracts
for six methods: extends
add
remove Map
removeAny
implements implements
value
hasKey
Map1L Map3
size Map2
7 January 2019 OSU CSE 5
Interfaces
Map and Classes
has contracts for five
other Standard
methods: Iterable
replaceValue
key extends extends
hasValue
sharesKeyWith MapKernel
combineWith
extends

Map
implements implements

Map1L Map3
Map2
7 January 2019 OSU CSE 6
Interfaces and Classes
Standard Iterable

extends extends
Iterable has a contract
MapKernel
for one method:
iterator
extends

Map
implements implements

Map1L Map3
Map2
7 January 2019 OSU CSE 7
Mathematical Model
• The value of a Map variable is modeled as
a finite set of ordered pairs of type (K, V)
with “the function property”, i.e., no two
pairs in the set have the same K value
– This is sometimes called a (finite) partial
function from K to V

7 January 2019 OSU CSE 8


Partial Function
PARTIAL_FUNCTION is finite set of
(key: K, value: V)
exemplar m
constraint
for all key1, key2: K, value1, value2: V
where ((key1, value1) is in m and
(key2, value2) is in m)
(if key1 = key2 then value1 = value2)

7 January 2019 OSU CSE 9


Partial Function
This formally states “the
PARTIAL_FUNCTION is function
finiteproperty”
set offor a set of
(key: K, value: V) ordered pairs.
exemplar m
constraint
for all key1, key2: K, value1, value2: V
where ((key1, value1) is in m and
(key2, value2) is in m)
(if key1 = key2 then value1 = value2)

7 January 2019 OSU CSE 10


Domain of a (Partial) Function
DOMAIN (
m: PARTIAL_FUNCTION
): finite set of K
satisfies
for all key: K
(key is in DOMAIN(m) iff
there exists value: V
((key, value) is in m))

7 January 2019 OSU CSE 11


Range of a (Partial) Function
RANGE (
m: PARTIAL_FUNCTION
): finite set of V
satisfies
for all value: V
(value is in RANGE(m) iff
there exists key: K
((key, value) is in m))

7 January 2019 OSU CSE 12


Mathematical Model
• Formally:
type Map is modeled by
PARTIAL_FUNCTION

7 January 2019 OSU CSE 13


No-argument Constructor
• Ensures:
this = { }

7 January 2019 OSU CSE 14


Example
Code State

Map<String,Integer> m =
new Map1L<>();

7 January 2019 OSU CSE 15


Example
Code State

Map<String,Integer> m =
new Map1L<>();

m = { }

7 January 2019 OSU CSE 16


add
void add(K key, V value)
• Adds the pair (key, value) to this.
• Aliases: references key, value
• Updates: this
• Requires:
key is not in DOMAIN(this)
• Ensures:
this = #this union {(key, value)}

7 January 2019 OSU CSE 17


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PS"
v = 99

m.add(k, v);

7 January 2019 OSU CSE 18


Example
Is the requires
Code clause State
satisfied? What is
DOMAIN(m)? m = {("PB", 99),
("BW", 17)}
k = "PS"
v = 99

m.add(k, v);

7 January 2019 OSU CSE 19


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PS"
v = 99

m.add(k, v);
m = {("PB", 99),
("BW", 17),
("PS", 99)}
k = "PS"
v = 99

7 January 2019 OSU CSE 20


Example
Code
Note the aliases created State
here, which you cannot m = {("PB", 99),
see in the tracing table; ("BW", 17)}
you should be able to k = "PS"
draw the appropriate v = 99
diagram showing them.
m.add(k, v);
m = {("PB", 99),
("BW", 17),
("PS", 99)}
k = "PS"
v = 99

7 January 2019 OSU CSE 21


Another Interface
• The Map interface includes an interface for
another related generic type, Map.Pair
• Its mathematical model is simply an
ordered pair of a key and a value
• Formally:
type Map.Pair is modeled by
(key: K, value: V)

7 January 2019 OSU CSE 22


Map.Pair Methods
• This (immutable) type has only a
constructor (taking a K and a V) and a
getter method for each pair component
– K key()
• Returns the first component of this
• Aliases: reference returned by key
– V value()
• Returns the second component of this
• Aliases: reference returned by value

7 January 2019 OSU CSE 23


remove
Map.Pair<K,V> remove(K key)
• Removes from this the pair whose first
component is key and returns it.
• Updates: this
• Requires:
key is in DOMAIN(this)
• Ensures:
remove.key = key and
remove is in #this and
this = #this \ {remove}

7 January 2019 OSU CSE 24


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "BW"
Map.Pair<String,Integer> p =
m.remove(k);

7 January 2019 OSU CSE 25


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "BW"
Map.Pair<String,Integer> p =
m.remove(k);
m = {("PB", 99)}
k = "BW"
p = ("BW", 17)

7 January 2019 OSU CSE 26


removeAny
Map.Pair<K,V> removeAny()
• Removes and returns an arbitrary pair from
this.
• Updates: this
• Requires:
|this| > 0
• Ensures:
removeAny is in #this and
this = #this \ {removeAny}
7 January 2019 OSU CSE 27
Example
Code State
m = {("PB", 99),
("BW", 17),
("PS", 99)}
Map.Pair<String,Integer> p =
m.removeAny();

7 January 2019 OSU CSE 28


Example
Code State
m = {("PB", 99),
("BW", 17),
("PS", 99)}
Map.Pair<String,Integer> p =
m.removeAny();
m = {("PB", 99),
("BW", 17)}
p = ("PS", 99)

7 January 2019 OSU CSE 29


value
V value(K key)
• Reports the value associated with key in
this.
• Aliases: reference returned by value
• Requires:
key is in DOMAIN(this)
• Ensures:
(key, value) is in this
7 January 2019 OSU CSE 30
Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = -423

v = m.value(k);

7 January 2019 OSU CSE 31


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = -423

v = m.value(k);
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 32


Example
Code
Note the alias created State
here, which you cannot m = {("PB", 99),
see in the tracing table; ("BW", 17)}
you should be able to k = "PB"
draw the appropriate v = -423
diagram showing it.
v = m.value(k);
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 33


hasKey
boolean hasKey(K key)
• Reports whether there is a pair in this
whose first component is key.
• Ensures:
hasKey =
(key is in DOMAIN(this))

7 January 2019 OSU CSE 34


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
boolean b =
m.hasKey(k);

7 January 2019 OSU CSE 35


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
boolean b =
m.hasKey(k);
m = {("PB", 99),
("BW", 17)}
k = "PB"
b = true

7 January 2019 OSU CSE 36


size
int size()
• Reports the size (cardinality) of this.
• Ensures:
size = |this|

7 January 2019 OSU CSE 37


replaceValue
V replaceValue(K key, V value)
• Replaces the value associated with key in this by
value, and returns the old value.
• Aliases: reference value
• Updates: this
• Requires:
key is in DOMAIN(this)
• Ensures:
this = (#this \ {(key, replaceValue)})
union {(key, value)} and
(key, replaceValue) is in #this

7 January 2019 OSU CSE 38


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 85
Integer oldV =
m.replaceValue(k, v);

7 January 2019 OSU CSE 39


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 85
Integer oldV =
m.replaceValue(k, v);
m = {("PB", 85),
("BW", 17)}
k = "PB"
v = 85
oldV = 99

7 January 2019 OSU CSE 40


Example
Code
Note the alias created State
here, which you cannot m = {("PB", 99),
see in the tracing table; ("BW", 17)}
you should be able to k = "PB"
draw the appropriate v = 85
diagramoldV
Integer showing
= it.
m.replaceValue(k, v);
m = {("PB", 85),
("BW", 17)}
k = "PB"
v = 85
oldV = 99

7 January 2019 OSU CSE 41


Another Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 85

v = m.replaceValue(k, v);

7 January 2019 OSU CSE 42


Another Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 85

v = m.replaceValue(k, v);

m = {("PB", 85),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 43


Another Example
This use of the method
Code State
avoids creating an alias: it
swaps v with the value in m = {("PB", 99),
("BW", 17)}
m that was previously
k = "PB"
associated with k. v = 85

v = m.replaceValue(k, v);

m = {("PB", 85),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 44


key
K key(V value)
• Reports some key associated with value
in this.
• Aliases: reference returned by key
• Requires:
value is in RANGE(this)
• Ensures:
(key, value) is in this
7 January 2019 OSU CSE 45
Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "xyz"
v = 99

k = m.key(v);

7 January 2019 OSU CSE 46


Example
Code State
m = {("PB", 99),
("BW", 17)}
k = "xyz"
v = 99

k = m.key(v);
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 47


Example
The method value is part of the
intended use of a Map and is
Code efficient in mostState
classes that
implementmMap; the method key is
= {("PB", 99),
rarely of interest("BW",
and is inefficient
17)} in
most classes
k = that implement Map.
"xyz"
v = 99

k = m.key(v);
m = {("PB", 99),
("BW", 17)}
k = "PB"
v = 99

7 January 2019 OSU CSE 48


hasValue
boolean hasValue(V value)
• Reports whether there is a pair in this
whose second component is value.
• Ensures:
hasValue =
(value is in RANGE(this))

7 January 2019 OSU CSE 49


Example
Code State
m = {("PB", 99),
("BW", 17)}
v = 17
boolean b =
m.hasValue(v);

7 January 2019 OSU CSE 50


Example
Code State
m = {("PB", 99),
("BW", 17)}
v = 17
boolean b =
m.hasValue(v);
m = {("PB", 99),
("BW", 17)}
v = 17
b = true

7 January 2019 OSU CSE 51


Example
The method hasKey is part of the
intended use of a Map and is
efficient in most classes that
Code implement Map;Statethe method
hasValuem is= rarely of interest
{("PB", 99), and
is inefficient in ("BW", 17)} that
most classes
v = 17
implement Map.
boolean b =
m.hasValue(v);
m = {("PB", 99),
("BW", 17)}
v = 17
b = true

7 January 2019 OSU CSE 52


combineWith
void combineWith(Map<K,V> m)
• Combines m with this.
• Updates: this
• Clears: m
• Requires:
DOMAIN(this) intersection
DOMAIN(m) = {}
• Ensures:
this = #this union #m
7 January 2019 OSU CSE 53
Example
Code State
m1 = {("PB", 99),
("BW", 17)}
m2 = {("PS", 99)}

m1.combineWith(m2);

7 January 2019 OSU CSE 54


Example
Code State
m1 = {("PB", 99),
("BW", 17)}
m2 = {("PS", 99)}

m1.combineWith(m2);
m1 = {("PB", 99),
("BW", 17),
("PS", 99)}
m2 = { }

7 January 2019 OSU CSE 55


sharesKeyWith
boolean sharesKeyWith(Map<K,V>
m)
• Reports whether this and m have any
keys in common.
• Ensures:
sharesKeyWith=
(DOMAIN(this) intersection
DOMAIN(m) /= {})
7 January 2019 OSU CSE 56
Example
Code State
m1 = {("PB", 99),
("BW", 17)}
m2 = {("PS", 99)}
boolean b =
m1.sharesKeyWith(m2);

7 January 2019 OSU CSE 57


Example
Code State
m1 = {("PB", 99),
("BW", 17)}
m2 = {("PS", 99)}
boolean b =
m1.sharesKeyWith(m2);
m1 = {("PB", 99),
("BW", 17)}
m2 = {("PS", 99)}
b = false

7 January 2019 OSU CSE 58


iterator
Iterator<Map.Pair<K,V>> iterator()
• Returns an iterator over a set of elements
of type Map.Pair<K,V>.
• Ensures:
entries(~this.seen * ~this.unseen) = this
and
|~this.seen * ~this.unseen| = |this|

7 January 2019 OSU CSE 59


Example
• Suppose you have a Map that keeps track
of the names and associated salaries of all
employees in the company:
Map<String,NaturalNumber> m =
new Map1L<>();
...

7 January 2019 OSU CSE 60


Sample For-Each Loop:
Danger!
• Here’s how you might try to give every
employee a $10,000 raise:
NaturalNumber raise =
new NaturalNumber2(10000);
for (Map.Pair<String,NaturalNumber> p : m) {
NaturalNumber salary = p.value();
salary.add(raise);
}

7 January 2019 OSU CSE 61


Sample For-Each Loop:
associated value Danger!
Draw this diagram: p holds aliases to some key and its
in m; the method value returns an
alias tohow
• Here’s a NaturalNumber
you might try thatto
is also
givein every
the Map m;
so, changing that NaturalNumber incidentally
employee
changes thea values
$10,000 raise:
of both p and m (even though no
NaturalNumber
Map raise
method =is called in the loop).
new NaturalNumber2(10000);
for (Map.Pair<String,NaturalNumber> p : m) {
NaturalNumber salary = p.value();
salary.add(raise);
}

7 January 2019 OSU CSE 62


Sample For-Each Loop:
Danger!
• Here’s how you might try to give every
employee a $10,000 raise:
NaturalNumber raise =
new NaturalNumber2(10000);
for (Map.Pair<String,NaturalNumber> p : m) {
NaturalNumber salary = p.value();
salary.add(raise);
Danger!
} This violates the rules for using
iterators and for-each loops!

7 January 2019 OSU CSE 63


The Safe Way
• Here’s how you should give every
employee a $10,000 raise:
NaturalNumber raise = new NaturalNumber2(10000);
Map<String, NaturalNumber> temp = m.newInstance();
temp.transferFrom(m);
while (temp.size() > 0) {
Map.Pair<String, NaturalNumber> p =
temp.removeAny();
p.value().add(raise);
m.add(p.key(), p.value());
}

7 January 2019 OSU CSE 64


The Safe Way
Draw this diagram: p holds references to some key
and its associated value, but now they are not in any
• Here’s howp is
Map and you give
in any Map;
not should every value
the method
returns an alias to a NaturalNumber in the
employee
Map.Paira p; $10,000 raise:
so, changing that NaturalNumber
NaturalNumber raise = new NaturalNumber2(10000);
does not incidentally change the value of m or temp
Map<String, NaturalNumber> temp = m.newInstance();
(even though that actually would be OK for this loop).
temp.transferFrom(m);
while (temp.size() > 0) {
Map.Pair<String, NaturalNumber> p =
temp.removeAny();
p.value().add(raise);
m.add(p.key(), p.value());
}

7 January 2019 OSU CSE 65


Resources
• OSU CSE Components API: Map
– http://cse.osu.edu/software/common/doc/

7 January 2019 OSU CSE 66

Das könnte Ihnen auch gefallen