How to filter map of map using java stream

ash*_*ish 2 java java-stream

How can I filter map of map using java stream. I can do it using double loop but I think this is not efficient.

public class MapUsage {
    static Map<Integer, Map<Integer, String>> parentMap = new HashMap<>();
    static Map<String, String> userRole = new HashMap<>();

    public static void main(String ... args){
        initializeData();
        displayMapForUser("user1", parentMap);
//        printMap(parentMap);

    }


    private static void displayMapForUser(String user1, Map<Integer, Map<Integer, String>> parentMap) {
        Integer role = new Integer(userRole.get(user1));
        Map<Integer, Map<Integer, String>> userMap = new HashMap<>();
        Map<Integer, String> childMap = new HashMap<>();
        for(Map.Entry<Integer, Map<Integer, String >> entry : parentMap.entrySet()){
            for(Map.Entry<Integer, String > entry1: entry.getValue().entrySet()){
                if(entry1.getKey().equals(role))
                    childMap.put(entry1.getKey(), entry1.getValue());
            }
            userMap.put(entry.getKey(), childMap);
        }
        printMap(userMap);
    }

    private static void printMap(Map<Integer, Map<Integer, String>> parentMap) {
        for(Map.Entry<Integer, Map<Integer,String> > entry: parentMap.entrySet()){
            System.out.println("key: "+entry.getKey());
            System.out.println("value: "+entry.getValue());
        }
    }

    private static void initializeData() {
        Map<Integer, String > childMap1 = new HashMap<>();
        Map<Integer, String > childMap2 = new HashMap<>();
        userRole.put("user1", "1");
        userRole.put("user2", "2");
        userRole.put("user3", "3");
        userRole.put("user4", "4");

        childMap1.put(1, "one");
        childMap1.put(2, "two");
        childMap1.put(3, "three");
        childMap1.put(4, "four");
        parentMap.put(1, childMap1);

        childMap2.put(1, "one");
        childMap2.put(2, "two");
        childMap2.put(3, "three");
        parentMap.put(2, childMap2);
    }
}
Run Code Online (Sandbox Code Playgroud)

Output is:

key: 1
value: {1=one}
key: 2
value: {1=one}
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 5

你可以Collectors.toMap在那里使用:

Map<Integer, Map<Integer, String>> userMap = parentMap.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue()
                .entrySet().stream()
                .filter(en -> en.getKey().equals(role))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
Run Code Online (Sandbox Code Playgroud)

但请注意,您在此处没有获得显着的性能效率。只是可读性,你可能会写成:

Map<Integer, Map<Integer, String>> usersMap = new HashMap<>(parentMap);
usersMap.values().forEach(innerMap -> innerMap.entrySet().removeIf(en -> !en.getKey().equals(role)));
Run Code Online (Sandbox Code Playgroud)

  • 我要指出的是,这与原始解决方案的复杂性大致相同,但增加的可读性是一个很好的改进。 (2认同)