有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

字典如何递归读取java映射

我有如下的Java地图。我想读取所有的值,其中键可以是其他键的值。在这里,我试图写一些反响的方法来阅读它,但没有运气。如果有人有经验,请向我解释

Map map= new HashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
map.put("1", "4");
map.put("4", "5");

在上面的映射中,如果我将"a"作为键传递,我需要与1,4,5对应的所有值


共 (3) 个答案

  1. # 1 楼答案

    假设没有任何循环:

    private String mapRecursion(Map<String,String> map, String key) {
        String s = map.get(key);
        if (map.get(s) == null) {
            return s;
        }
        return s + "," + mapRecursion(map, s);
    }
    
  2. # 2 楼答案

    您可以通过从一个键开始并返回方法调用及其值来递归地导航映射

    import java.util.*;
    
    public class RecurseMap {
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<>();
            map.put("a", "1");
            map.put("b", "2");
            map.put("c", "3");
            map.put("1", "4");
            map.put("4", "5");
            map.put("5", "a"); // Circular reference!
    
            navigate(map, "a");
        }
    
        public static <K, V> void navigate(Map<K, V> map, K key) {
            navigate(map, key, new TreeSet<K>());
        }
    
        @SuppressWarnings("unchecked")
        public static <K, V> void navigate(Map<K, V> map, K key, Set<K> visited) {
            System.out.println(String.format("Current key: %s", key));
            if (!visited.contains(key) && map.containsKey(key)) {
                visited.add(key);
                navigate(map, (K) map.get(key), visited);
            }
        }
    }
    

    输出

    Current key: a
    Current key: 1
    Current key: 4
    Current key: 5
    Current key: a
    

    请记住,方法签名应该是<K, K><K>,但我在上面使用了<K, V>来表示键、值关系

    public static <K> void navigate(Map<K, K> map, K key) {
        navigate(map, key, new TreeSet<K>());
    }
    
    public static <K> void navigate(Map<K, K> map, K key, Set<K> visited) {
        System.out.println(String.format("Current key: %s", key));
        if (!visited.contains(key) && map.containsKey(key)) {
            visited.add(key);
            navigate(map, (K) map.get(key), visited);
        }
    }
    

    在地图上行走

    更新:您可以创建一个访问者类来评估地图键/值

    import java.util.*;
    
    public class RecurseMap {
        private static interface Visitor<K> {
            void visit(K key, K value, Map<K, K> map);
        }
    
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<>();
            map.put("a", "1");
            map.put("b", "2");
            map.put("c", "3");
            map.put("1", "4");
            map.put("4", "5");
            map.put("5", "a"); // Circular reference!
    
            walkMap(map, "a", new Visitor<String>() {
                @Override
                public void visit(String key, String value, Map<String, String> mapRef) {
                    System.out.println(String.format("Current key: %s", key));
                }
            });
        }
    
        public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor) {
            walkMap(map, key, visitor, new TreeSet<K>());
        }
    
        public static <K> void walkMap(Map<K, K> map, K key, Visitor<K> visitor, Set<K> visited) {
            if (!visited.contains(key) && map.containsKey(key)) {
                K value = map.get(key);
                visitor.visit(key, value, map);
                visited.add(key);
                walkMap(map, value, visitor, visited);
            }
        }
    }
    
  3. # 3 楼答案

    为了防止Java.lang.StackOverflowError,如果在映射中发生循环,您可以检查该值是否已经存在,并将continer(这里是Set)提供给该方法,而不让该方法自己创建它

    static Set<String> getValues(Map<String, String> map, String key, Set<String> res) {
        String val = map.get(key);
        if (val != null && !res.contains(val)) {
            res.add(val);
            res.addAll(getValues(map, val, res));
        }
        return res;
    }
    
    //Use as 
    Set<String> res = getValues(map, "a", new HashSet<>());
    System.out.println(res);