Alternatively, as I suggested in an earlier post to this thread, you
can use self-balancing trees like RB-tree to resolve collisions
instead of lists when lists get larger.
I like this approach, and I've used it before for symbol tables, using a fixed number of hash buckets. You get good performance for normal cases, and it only deteriorates to O(log(N)) for degenerate cases. I used treaps, not read-black trees, but the principle is the same.