Fixes and improvements to IntObjectHashMap

- Rewrite with linear probing, no state array, compaction at cleanup
- Optimize keys() and values() to not use reflection
- Optimize hashCode() and equals() for efficient iteration
- Fixed equals() to not return true for equals(null)
- Optimize iterator to not allocate new Entry at each next()
- Added toString()
- Added some new unit tests
Fixed already, working on improved tests for this now... in fact the code was handling NULL_VALUE, but incorrectly. Also, the original code has a bug in hashCode(); if you examine it, the hashCode function depends on the internal order of entries: values=[1,2] and values=[2,1] will produce different hashes. This difference of ordering is possible when the maps had different hashing conflicts, e.g. the natural placement would be [1,2] but insertion history was something like [-,-] =(put 8)=> [8,-] =(put 1)=> [8,1] =(remove 8)=> [-,1] =(put 2)=> [2,1]. And even when you hit this scenario, which may be very hard in artificial unit tests not designed to build hashtables in a messy way, your test may still succeed if it uses only equals() but not hashCode() (rare real-world code will use hashtables as values inside other hashtable). The new hashCode() function already avoids this bug, but I'm adding a commente there and also tests to watch for this...