Methods for finding keys in the map would iterate over all keys
when the key did not exist.
Fixed by introducing a new sentinel value (-1) that is used to
mark slots that were previously occupied.
In many use cases it is more efficient to have a getter that returns
a default value instead of throwing an exception. The exception forces
every consumer to call containsKey() before calling get(). In cases
where the consumer wants to use a default value this is unnecessary.