import java.util.*;
public class Main {
	@SuppressWarnings("serial")
    public static void main(String[] args) {
        final Map<String, Object> dates = new HashMap<String, Object>() {
            {
                put("1999", new HashMap<String, Object>() {
                    {
                        put("3", Arrays.asList("23", "24", "25"));
                        put("4", Arrays.asList("1", "2", "3"));
                    }
                });
                put("2001", new HashMap<String, Object>() {
                    {
                        put("11", new HashMap<String, Object>() {
                            {
                                put("7", Arrays.asList("23", "24", "25"));
                                put("9", Arrays.asList("1", "2", "3"));
                            }
                        });
                        put("12", "45");
                    }
                });
            }
        };
        final Map<String, Object> flattened = flatten(dates);
        System.out.println(flattened);
    }

    public static Map<String, Object> flatten(final Map<String, Object> map) {
        return flatten("", map, new HashMap<>());
        // use new TreeMap<>() to order map based on key
    }

    @SuppressWarnings("unchecked")
    private static Map<String, Object> flatten(final String key, final Map<String, Object> map,
            final Map<String, Object> result) {
        final Set<Map.Entry<String, Object>> entries = map.entrySet();
        if (!entries.isEmpty()) {
            for (final Map.Entry<String, Object> entry : entries) {
                final String currKey = key + (key.isEmpty() ? "" : '.') + entry.getKey();
                final Object value = entry.getValue();
                if (value instanceof Map) {
                    flatten(currKey, (Map<String, Object>) value, result);
                } else if (value instanceof List) {
                    final List<Object> list = (List<Object>) value;
                    for (int i = 0, size = list.size(); i < size; i++) {
                        result.put(currKey + '.' + (i + 1), list.get(i));
                    }
                } else {
                    result.put(currKey, value);
                }
            }
        }
        return result;
    }
}