[I come from C# background, but the answer should apply]
[It doesn't much matter but I assume the last item is ConcurrentHashMap<C,Integer>]
You have a function f of type A --> (B --> (C --> int))
If it is really what you need, I don't have a ready answer. But perhaps, having a function f of type (A x B x C) --> int would be enough for your purposes.
The difference between two cases is, the first one is lazier, more functional, arguably more elegant and it is possible to have a "partially applied" function around. For example, you have an a (of type A) element, you apply a to f and have a function g of type (B --> (C --> int)) to pass around, send to methods, whatever. However it is a little cumbersome and a little more code to properly initialize the function.
The second is more eager and less elegant, but may be easier to code and understand. All you need to do is to have a generic class Triple<A,B,C>, override Equals() and GetHashCode() so that it will have value semantics, (two instances are to be considered equal if they have equal elements) and declare the ConcurrentHashMap is from Triple to Integer. The most obvious cost to pay is you need to have the A, B, C elements ready all at once to create an instance of Triple and perform the lookup.
Edit: If the last item is really ConcurrentHashMap<C,Integer>, then your generic class will have A, B and Integer fields, and the mapping will be from Triple<A,B,Integer> to C
A
,B
, andC
? It would be easier to answer if I could understand the meaning of three-level nesting of your has maps there.ConcurrentHashMap
s at every level of nesting?