What is the best way in Java to keep values (“o”) in a tree structure like this:
obj1
/\
/ \
/ \
obj2 obj3
/\ /\
/ \ / \
/ \ / \
obj4 obj5 obj6 obj7
/\ /\ /\ /\
/ \ / \ / \ / \
o8 oN...
It looks like a tree, but I don’t need arbitrary depth. I rather need strong datatyping and predefined good looking methods for working with final structure.
I need to be able to get some kind of list of values by keys – exactly like on my picture. In other words, structure should not become planar in any way.
I need .get(obj3) to return {obj6, obj7}, .get(obj1) - {obj2, obj3}.
For now I use Map for that, but inflating such map is ugly, because I need to check each level of the structure. Looks like that (data is the map):
if(data.get(somedouble) == null) {
Map<Integer, Data> inm = new TreeMap<>();
inm.put(someint, obj);
Map<Double, Map<Integer, Data>> m = new TreeMap<>();
m.put(somedouble2, inm);
data.put(somedouble, m);
}
else {
if(data.get(somedouble).get(somedouble2) == null) {
Map<Integer, Data> inm = new TreeMap<>();
inm.put(someint, obj);
data.get(somedouble).put(somedouble2, inm);
}
else
data.get(somedouble).get(somedouble2).put(someint, obj);
}
Performance in not an issue, but code beauty is.
You can use your specific key:
And then simply:
This way the “multi-level checks” are all hidden in
MyKey.equals(). It keeps the client code clean and the key complexity is in a safe place.Edit after requirement changes:
If on top of this, you want to be able to have a map from your double
betato your objects, then I would still keep the thing planar like that.What you actually want is to have multiple “indexes” for your data, like in a database, so you can query for objects with same “beta” or “yaw”. For that the best way is to use several Map (actually Multimap), one for each of your “indexes”.
Using Guava’s Multimap:
You can put all the multimap and the
Map<MyKey, Data>in your a specific class. Actually the best way would be to subclassMap<MyKey, Data>:New Edit with better solution:
Actually, it got me thinking, and I realized that you are really having a problem with default values for your maps, and that’s why your code is a bit messy.
You can solve this with a Default Map using a generator to create underlying maps:
Now you can have your utility tree class to store all your data :
Now you can access your data with data.get(beta).get(yaw) and you don’t have spaghetti code to store your values.