How to make Map expendible(?) safely in java
It took a long time just to understand what your program is doing and how it might be useful.
You were concerned about the unchecked casting, and that's a valid concern, but maybe it's not a problem if you make that behaviour clear, for instance, by including a failure scenario in the test case or JavaDoc, in which case you are just stating it's the responsibility of the other code that makes use of this to only pass valid arguments.
Here's a version of the same thing that's hopefully a bit better at describing what it does. With things a bit more plain to read, you can decide if you want your program to behave differently in the failure case -- maybe it should throw a checked exception instead of ClassCastException or maybe you want to actually support these cases?
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

/**
 * 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.
 *
 */
public class StatisticsCounter {

    private Map&lt;String, Object&gt; rootMap = new HashMap&lt;&gt;();

    public void increment(String... paths) {
        recursiveIncrement(rootMap, paths, 0);
    }

    private void recursiveIncrement(Map&lt;String, Object&gt; targetMap, String[] pathToTarget,
            int pathIndex) {

        final int targetDepth = pathToTarget.length - 1;
        final String counterName = pathToTarget[pathIndex];

        if (pathIndex == targetDepth &amp;&amp; targetMap.containsKey(counterName)) {
            // assume objects at the target depth are int
            targetMap.put(counterName, (int) targetMap.get(counterName) + 1);
        } else if (pathIndex == targetDepth) {
            // at the target depth, put ints
            targetMap.put(counterName, 1);
        } else if (targetMap.containsKey(counterName)) {
            // assume object is a map, recur into it for the next counter name
            recursiveIncrement((Map&lt;String, Object&gt;) targetMap.get(counterName),
                    pathToTarget, pathIndex + 1);
        } else {
            // create a new map and recur into it for the next counter name
            Map&lt;String, Object&gt; emptyMap = new HashMap&lt;&gt;();
            targetMap.put(counterName, emptyMap);
            recursiveIncrement(emptyMap, pathToTarget, pathIndex + 1);
        }
    }

    public String toString() {
        return rootMap.toString();
    }

    @Test
    public void test() {
        StatisticsCounter counters = new StatisticsCounter();
        counters.increment(&quot;USA&quot;, &quot;California&quot;, &quot;Los Angeles&quot;);
        counters.increment(&quot;USA&quot;, &quot;California&quot;, &quot;Los Angeles&quot;);
        counters.increment(&quot;USA&quot;, &quot;California&quot;, &quot;San Diego&quot;);
        counters.increment(&quot;USA&quot;, &quot;California&quot;, &quot;Bay Area&quot;, &quot;San Francisco&quot;,
                &quot;Financial District&quot;);
        counters.increment(&quot;USA&quot;, &quot;Tennessee&quot;, &quot;Memphis&quot;);
        counters.increment(&quot;USA&quot;, &quot;Tennessee&quot;, &quot;Memphis&quot;);
        counters.increment(&quot;Italy&quot;, &quot;Venice&quot;);
        counters.increment(&quot;Italy&quot;, &quot;Rome&quot;);
        counters.increment(&quot;Italy&quot;, &quot;Venice&quot;);
        counters.increment(&quot;Vatican City&quot;);
        counters.increment(&quot;Vatican City&quot;);

        try {
            counters.increment(&quot;USA&quot;, &quot;California&quot;);
            fail(&quot;Cannot increment a key that already has subcounters&quot;);
        } catch (ClassCastException expectedException) {
            assertEquals(&quot;java.util.HashMap cannot be cast to java.lang.Integer&quot;,
                    expectedException.getMessage());
        }

        try {
            counters.increment(&quot;USA&quot;, &quot;Tennessee&quot;, &quot;Memphis&quot;, &quot;Graceland&quot;);
            fail(&quot;Cannot add subcounters to a key that already has a count&quot;);
        } catch (ClassCastException expectedException) {
            assertEquals(&quot;java.lang.Integer cannot be cast to java.util.Map&quot;,
                    expectedException.getMessage());
        }

        System.out.println(counters);
        // {USA={Tennessee={Memphis=2}, California={San Diego=1, Bay Area={San
        // Francisco={Financial District=1}}, Los Angeles=2}}, Italy={Rome=1, Venice=2},
        // Vatican City=2}
    }
}