I am building some statistic counter in Java. Each metric could have flexible depth so the implementation should able to explore the depth when value insert or update.
So I implement like below (with Test)
public class TestRecursiveMap {
private void recursiveRegister(Map<String, Object> target, String[] keys, int curr) {
if(curr > keys.length -1) return;
String currKey = keys[curr];
if(target.containsKey(currKey)) {
Object currVal = target.get(currKey);
if(curr >= keys.length -1) {
int value = (int) currVal;
target.put(currKey, value + 1);
} else {
Map<String, Object> subMap = (Map<String, Object>)currVal;
recursiveRegister(subMap, keys, curr + 1);
}
} else {
if(curr >= keys.length -1) {
target.put(currKey, 1);
} else {
Map<String, Object> emptyMap = new HashMap<>();
target.put(currKey, emptyMap);
recursiveRegister(emptyMap, keys, curr + 1);
}
}
}
// result looks like
// {a={b={c=1}}}
// {a={b={c=2}}}
@Test
public void testRecursive(){
Map<String, Object> originMap = new HashMap<>();
String[] keys = {"a", "b", "c"};
recursiveRegister(originMap, keys, 0);
System.out.println(originMap);
recursiveRegister(originMap, keys, 0);
System.out.println(originMap);
}
}
The code is so unsatisfied because of
casting in recursive logic -
Map<String, Object>is very flexible but need to cast object to map or integer in every levelwhile casting there are bunch of possibilities of exceptions
How could I implement this safe and fast?
=====================================
Use case #1.
Actually this is an api counter. When you have an API call, it will counting the mount of the request.
For instance,
/api/user/1 and /api/v1/user/1 then it will have some value like below (in JSON form)
{
"api" : {
"user" : {
"1" : 1
},
"v1" : {
"user" : {
"1" : 1
}
}
}
}
So the basic logic is
- if there is a key in the map, it will increase the number
- if not, it will assign new k,v set and the initial value is 1
Map<Path, Object>?) And a well known design pattern exists (Container). But show us the desired API in some unit tests, how to store, how to query. Does get("a") return a list of either values or "b" pointing to further subhierarchies. If we know the API we'll can start searching for a fitting data structure. \$\endgroup\$