'Recursive iteration of a Map Java

I am writing a recursive function whose purpose is to iterate over the pList File. My code is

public static void HashMapper(Map lhm1) throws ParseException {

    //Set<Object> set = jsonObject.keySet();
    for (Object entry : lhm1.entrySet()) {
        if(entry instanceof String)
        {
            System.out.println(entry.toString());
        }
        else
        {
            HashMapper((Map) ((Map) entry).keySet()); //getting Exception java.util.HashMap$HashMap Entry cannot be cast to java.util.Map
        }
    }
}

But when i am calling my function "HashMapper((Map) ((Map) entry).keySet());". I am getting an exception of

java.util.HashMap$HashMap Entry cannot be cast to java.util.Map

I donot know how to call my function and how can i convert Hashmap entry to Map



Solution 1:[1]

Entry is indeed not String. It is Map.Entry, so you can cast it to this type if you need.

However since java 1.5 that was introduced ~10 years ago you almost do not really need casting. Instead define map with generic and use type-safe programming.

Unfortunately your code is not so clear. Do you mean that key or value of your map is String? Let's assume that key is string and value can be either string or map. (BTW this extremely bad practice, so I'd recommend you to ask other question where you describe what your task is and ask how to design your program.)

But anyway here is what I can suggest you so far:

public static void hashMapper(Map<String, Object> lhm1) throws ParseException {
    for (Map.Entry<String, Object> entry : lhm1.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        if (value instanceof String) {
             System.out.println(value);
        } else if (value instanceof Map) {
            Map<String, Object> subMap = (Map<String, Object>)value;
            hashMapper(subMap);
        } else {
             throw new IllegalArgumentException(String.valueOf(value));
        }

    }
}

Solution 2:[2]

AlexR's answer is good, but in my case, I need process a map deserialize from json.

So I need more type handle(ex: array, boolean, number...).

Here is my improved version.

@Slf4j
public class DesensitizationUtil {

    private static void desensitizationMapSubProcessor(Map<String, Object> map, String key, Object value) {
        if (value == null) {
            log.debug("map key : {}, value : null", key);
            return;
        }
        log.debug("map key : {}, value : {}, value class : {}", key, value, value.getClass());
        if (value instanceof String || value instanceof Integer || value instanceof Boolean || value instanceof Double) {
            //your business logic here
        } else if (value instanceof List) {
            List list = (List) value;
            for (Object object : list) {
                desensitizationMapSubProcessor(map, key, object);
            }
        } else if (value instanceof Map) {
            try {
                //noinspection unchecked
                Map<String, Object> subMap = (Map<String, Object>) value;
                desensitizationMap(subMap);
            } catch (ClassCastException e) {
                log.warn("cast map failed", e);
            }
        } else {
            throw new IllegalArgumentException(String.valueOf(value));
        }
    }

    public static void desensitizationMap(Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            desensitizationMapSubProcessor(map, key, value);
        }
    }
}

Solution 3:[3]

If you want to containers of type List and Map, try this:

public static void printContainer(Object cont) {
    printContainer(cont, 0);
}

public static void printContainer(Object cont, final int level) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < level; ++i) sb.append(" ");
    if (cont instanceof List) {
        List<Object> ls = (List<Object>)cont;
        ls.forEach(obj -> {
            if (obj == null)
                log.info("{}array v: null", sb);
            else if (obj instanceof List || obj instanceof Map) {
                printContainer(obj, level + 1);
            }
            else if (obj instanceof String) {
                log.info("{}v:{}", sb, obj);
            }});
    } else if (cont instanceof Map) {
        Map<String, Object> mp = (Map<String, Object>)cont;
        for (Map.Entry<String, Object> entry : mp.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof String) {
                log.info("{}k:{} -> v:{}", sb, key, value);
            } else if (value instanceof Map) {
                log.info("{}map:{}", sb, key);
                printContainer(value, level + 1);
            } else if (value instanceof List) {
                log.info("{}array:{}", sb, key);
                printContainer(value, level + 1);
            } else if (null == value) {
                log.info("{}k:{} -> v:{}", sb, key, value);
            } else {
                throw new IllegalArgumentException(String.valueOf(value));
            }
        }
    } else {
        throw new IllegalArgumentException(String.valueOf(cont));
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AlexR
Solution 2 min
Solution 3 paiego