More information about your use-case would be helpful, whether this is a solution to a problem or an exercise, for example.
if(curr > keys.length -1) return;
// ...
Object currVal = target.get(currKey);
Don't shorten variable names just because you can. It makes the code harder to read and harder to maintain.
if(curr > keys.length -1) return;
Ideally you're always use a "full block if" for statements, as it makes it easier to see the return condition.
if (curr > keys.length - 1) {
return;
}
Also, your formatting seems to be off in a few cases. I'd suggest to always use an automatic formatter in your workflow so that you never need to worry about the formatting of your code ever again.
---
```java
target.put(currKey, 1);
int and Integer are requiring conversion between each other, that's called "boxing" and might or might not be a problem when doing it implicit.
You ain't got any sort of error handling, if I see this right.
So, let's get to the design. If I understand your example right, what you want to do is to have a list of keys, which represent the path through the tree structure, and the last key keeps a counter how often it was added.
There are several ways to achieve that, and the question is what exactly you're trying to achieve to know which one applies.
For every further implementation, we'll assume the following interface:
public class CounterTreeMap {
public int getValue(String... keys);
public void putValue(String... keys);
}
You notice that we've already simplified how to use this class, the rest are implementation details. Additionally, I'll skip tests on the input parameters for brevity.
The cheap one
The cheapest solution is to "fake" depth by hashing the input array and having a single Map. However, this implementation would be able to store a value for the path "A, B" as well as for "A, B, C".
protected Map<Integer, Integer> values = new HashMap<>();
public int getValue(String... keys) {
int keysHash = Arrays.hashCode(keys);
// TODO We are missing logic here to handle possible hash collisions.
Integer value = values.get(Integer.valueOf(keysHash));
if (value != null) {
return value.intValue();
} else {
return -1; // Or throw exception here.
}
}
The nearly as cheap one
Given the problems from the previous implementation, we can fix at least the possible has collisions by using the full path as key instead.
protected Map<String, Integer> values = new HashMap<>();
public int getValue(String... keys) {
String key = String.join("---", keys);
Integer value = values.get(Integer.valueOf(key));
if (value != null) {
return value.intValue();
} else {
return -1; // Or throw exception here.
}
}
Now that solves the possible hash collisions, but still allows us to store values at each node, basically. That might even be wanted, I don't know, you never specified.
The one with the many maps
As you've done, we can build a hierarchy of Maps, however, I'd base decisions on the type of the encountered leaf.
Recursive implementation:
protected Map<String, Object> tree = new HashMap<>();
public int getValue(String... keys) {
return getValue(tree, keys, 0);
}
protected int getValue(Map<String, Object> branch, String[] keys, int currentKeyIndex) {
String key = keys[currentKeyIndex];
Object value = branch.get(key);
if (value == null) {
return -1; // Or throw an exception here.
} else if (value instanceof Integer) {
return ((Integer)value).intValue();
} else if (value instanceof Map<?, ?>) {
return getValue((Map<String, Object)value, keys, currentKeyIndex + 1)
}
}
Implementation using a loop instead:
protected Map<String, Object> tree = new HashMap<>();
public int getValue(String... keys) {
Map<String, Object> branch = tree;
int currentKeyIndex = 0;
while (branch != null) {
String key = keys[currentKeyIndex];
Object value = branch.get(key);
if (value == null) {
return -1; // Or throw an exception here.
} else if (value instanceof Integer) {
return ((Integer)value).intValue();
} else if (value instanceof Map<?, ?>) {
branch = (Map<String, Object)value;
currentKeyIndex++;
}
}
}
Both implementations lack proper checks, though, but you should get the idea.