JacobASeverson JacobASeverson - 1 month ago 6
Java Question

Map entry appears in HashMap.entrySet() but not internal HashMap.table

I have a Java HashHap that is getting populated within the program. For some reason the entrySet within the map contains what I am expecting, but when I look at the internal Entry table it is missing a value. Since that value is missing I'm getting a null and it breaks everything. Maybe I don't understand HashMaps as well as I thought but should the table contain all the entries in the entrySet? Thanks.

When talking about entrySet and the table I am indeed talking about the internals of the HashMap when debugging. Here is what my "entrySet" looks like:

[IS_DELETED=0, COLLECTION_SET_NAME=D-EIUCFOE-SET, MAP_ID=Ic65fd5ffb7c311e09fc6842b2ba7e81a, PRODUCT_ID=1, USER_ID=U0158703, WM_DIFFVER=DiffBase, DISTRICT_CODE=TX_N_DIS, WM_CODE=NC, MODIFIED_DATE=2012-09-04 10:13:08.973]

And here is what my table looks like:

[IS_DELETED=0, COLLECTION_SET_NAME=D-EIUCFOE-SET, null, null, PRODUCT_ID=1, null, null, null, WM_DIFFVER=DiffBase, null, DISTRICT_CODE=TX_N_DIS, WM_CODE=NC, MODIFIED_DATE=2012-09-04 10:13:08.973, null, null, null]

So when my code looks for the MAP_ID once this HashMap is created, it comes up with a null and it blows up.

table HashMap$Entry<K,V>[16] (id=248)
[0] HashMap$Entry<K,V> (id=270)
hash -1013369904
key "IS_DELETED" (id=883)
next null
value BigDecimal (id=884)
[1] HashMap$Entry<K,V> (id=271)
hash 449814449
key "COLLECTION_SET_NAME" (id=896)
next HashMap$Entry<K,V> (id=898)
value "D-EIUCFOE-SET" (id=899)
[2] null
[3] null
[4] HashMap$Entry<K,V> (id=275)
hash -1942791868
key "PRODUCT_ID" (id=900)
next HashMap$Entry<K,V> (id=901)
value BigDecimal (id=902)
[5] null
[6] null
[7] null
[8] HashMap$Entry<K,V> (id=276)
hash -1109968520
key "WM_DIFFVER" (id=904)
next null
value "DiffBase" (id=905)
[9] null
[10] HashMap$Entry<K,V> (id=278)
hash -1920690854
key "DISTRICT_CODE" (id=906)
next null
value "TX_N_DIS" (id=907)
[11] HashMap$Entry<K,V> (id=279)
hash -1948303941
key "WM_CODE" (id=909)
next null
value "NC" (id=910)
[12] HashMap$Entry<K,V> (id=280)
hash 1002278668
key "MODIFIED_DATE" (id=912)
next null
value TIMESTAMP (id=913)
[13] null
[14] null
[15] null

I can't get a hold of the MAP_ID Entry but that is coming back from the database as a String.


Let's clarify a few things.

  1. Map.Entry is a logical "entry" in your map. Let's refer to it as a "map entry"
  2. HashMap.table is an internal array of the HashMap Map implementation, storing lists of "map entries" with colliding hashCode modulo values. Note that several "map entries" are contained in such a "hashmap table entry" (also referred to as "bucket")

Look at this "hashmap table entry" for instance:

[4] HashMap$Entry<K,V>  (id=275)    
    hash    -1942791868 
    key "PRODUCT_ID" (id=900)   
    next    HashMap$Entry<K,V>  (id=901)    
    value   BigDecimal  (id=902)    

Observe, that it links to id=901, which is the "next" "map entry" for the same hash value (or more precisely, hash % 16 == 4). The basic idea is this:

// "HashMap table" has 16 "hashmap table entries" (at first, before growing)
[0] with   1 "hashmap entry"
[1] with > 1 "hashmap entry"
[2] empty
[3] empty

While a HashMap grows, it may choose to enlarge its internal "hashmap table", in order to optimise the distribution of "map entries" across its "hashmap table". E.g. if the "hashmap table" has a size of 256, the modulo applied to hashCode() values will be 256 as well, reducing the hashCode() collision risk