简体   繁体   English

使用 Java Stream API 按其值过滤映射

[英]Filter map by its value using Java Stream API

I am new to Java streams and want to run the below code using streams.我是 Java 流的新手,想使用流运行以下代码。

 List<String> roles = new ArrayList<>();
    if (stats.containsKey("roles")) {
            roles = stats.get("roles");
    } else {
            Map<String, String> roleMap = stats.containsKey("attributes") ? 
                       stats.get("attributes") : new HashMap<>();
            for (Map.Entry<String, String> e : roleMap.entrySet()) {
                    if (e.getValue().equals("true")) {
                            roles.add(e.getKey());
                    }
            }
    }

In the above code I am doing the following steps :在上面的代码中,我正在执行以下步骤:

  1. I have a stats hashmap in which first I am checking if the roles key is present, if it is present I am returning the corresponding value.我有一个stats hashmap,首先我检查roles键是否存在,如果存在,我将返回相应的值。

  2. if the stats hashmap does not contain the roles key, I am checking if stats hashmap contains key attributes .如果stats hashmap 不包含roles键,我正在检查stats hashmap 是否包含 key attributes

  3. If the attribute key present then its value is Hashmap and then I am traversing the hashmap and checking wherever its value is equal to "true", I am adding the corresponding key to my roles list.如果存在attribute键,则其值为 Hashmap,然后我将遍历哈希图并检查其值等于“true”的任何位置,我将相应的键添加到我的roles列表中。

Input:输入:

{
    "attributes":{
        "id":false
        "name":true
    }
       
}

Output:输出:

["name"]

Can this whole code be reduced by streams?可以通过流减少整个代码吗?

Not sure how much this will help.不知道这会有多大帮助。 Using streams in your use case according to me is not simplifying the solution, but if you want to use then you can do something like this in your code.根据我的说法,在你的用例中使用流并没有简化解决方案,但是如果你想使用那么你可以在你的代码中做这样的事情。

 Map<String,Object> stats=new HashMap<>();
       List<String> roles = new ArrayList<>();
        stats.entrySet().stream()
                .forEach(i -> {
                    if (i.getKey().contains("roles")) {
                        roles.add((String)i.getValue());
                    } else if(i.getKey().contains("attributes")){
                        Map<String, String> roleMap=  (Map<String, String>)i.getValue();
                        roleMap.entrySet().stream().forEach(j-> {
                            if (j.getValue()
                                .equalsIgnoreCase("true"))
                                roles.add(j.getKey());
                    });
                    }
                });
 stats.keySet().stream().filter(s->s.equals("roles")).findFirst().map(s->stats.get("roles")).orElseGet(()->{
        List list=  Lists.newArrayList();
        stats.get("attributes").foreach((k,v)->{
             if v;list.add(k)
         })
       return list;
    })

If the values of the keys roles and attributes were of same type ( List<String> ) you could easily do something like如果键rolesattributes的值属于相同类型( List<String> ),您可以轻松地执行类似的操作

List<String> roles = stats.getOrDefault("roles",
                          stats.getOrDefault("attributes", new ArrayList<>()));

You could still use this approach, but since the assosiated values are of different types you need to make some casting which makes your code maybe a little bit unintuitive:您仍然可以使用这种方法,但由于关联值是不同类型的,您需要进行一些转换,这会使您的代码可能有点不直观:

Map<String, Object> stats = new HashMap<>();
stats.put("roles", Arrays.asList("role1", "role2"));
stats.put("attributes", Map.of("id", "false", "name", "true"));

List<String> roles = (List<String>) stats.getOrDefault("roles",
                     ((Map<String, String>) stats.getOrDefault("attributes", new HashMap<>()))
                                        .entrySet()
                                        .stream()
                                        .filter(i -> i.getValue().equalsIgnoreCase("true"))
                                        .map(Map.Entry::getKey)
                                        .collect(Collectors.toList()));
System.out.println(roles);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM