Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

My question is rather a design question. In my program I got to a data structure that looks something like this:

private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services  = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();

Is there a way to handle such a data structure more elegantly? Thanks!

edit: A, B and C are business classes. An A instance "can have" (as association) many Bs and a B "can have" many mappings Integer-C.

share|improve this question

migrated from stackoverflow.com Jan 13 '12 at 16:19

This question came from our site for professional and enthusiast programmers.

    
What types are A, B, and C? It would be easier to answer if I could understand the meaning of three-level nesting of your has maps there. –  dasblinkenlight Jan 13 '12 at 15:20
1  
Without knowing something about the domain, I don't think there's a general solution. Depending on how the maps are being used, you might consider replace one or more of the maps with classes that export a specific set of properties. –  Ernest Friedman-Hill Jan 13 '12 at 15:22
4  
Consider using objects encapsulating behavior, rather than dumb datastructures. Each of these maps should probably be wrapped into a specific object. –  JB Nizet Jan 13 '12 at 15:25
    
As an aside, do you really need to use ConcurrentHashMaps at every level of nesting? –  Russell Jan 13 '12 at 15:26
    
@ErnestFriedman-Hill: I was thinking that it may be so - that there is no "general solution", only a business-related one. –  ovdsrn Jan 13 '12 at 15:28

2 Answers 2

up vote 12 down vote accepted

Create a class Triple with fields for A,B,Integer, override hashCode() and equals(), and use Map<Triple,C> instead of Map<A,Map<B,Map<Integer,C>>>

In this approach - you put all elements in one map, with a larger possible range of keys.

share|improve this answer
    
Will the downvoter explain? I assumed here the OP actually is trying to map : (A,B,Integer) -> C, and thus the nested Map usage. The edit also supports my preception. –  amit Jan 13 '12 at 15:30
2  
Correct, this is what I'm trying to map: (A, B, Integer) to C. –  ovdsrn Jan 13 '12 at 15:34
    
+1 for guessing what the OP actually wanted to do. –  JB Nizet Jan 13 '12 at 15:58
    
I'll also add, name the Triple class something meaningful in your business domain. It must mean something :-) –  Martijn Verburg Jan 14 '12 at 10:37

[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

share|improve this answer
    
Maybe call it Triple instead of MyClass to clarify; there are also n-tuple implementations around the web, if you are really lazy. –  Viruzzo Jan 13 '12 at 15:50
    
Thanks, I changed the wording. –  Ali Jan 13 '12 at 15:58
    
Actually, the last map is ConcurrentHashMap<Integer, C>, not ConcurrentHashMap<C, Integer>, but it's just a minor detail, since from your answer I see you understood it correct. –  ovdsrn Jan 16 '12 at 10:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.