【问题标题】:Java 8 Filter Map<String,List<Employee>>Java 8 过滤器映射<String,List<Employee>>
【发布时间】:2019-01-08 19:48:03
【问题描述】:

如何使用 Java 8 过滤器过滤 Map&lt;String, List&lt;Employee&gt;&gt;

只有当列表中的任何员工具有字段值Gender = "M" 时,我才需要过滤。

输入:Map&lt;String,List&lt;Employee&gt;&gt;
输出:Map&lt;String,List&lt;Employee&gt;&gt;
过滤条件:Employee.genter = "M"

如果列表在映射值上为空,我还必须过滤掉输出映射(或过滤映射[过滤后得到的新映射])中的键

【问题讨论】:

  • 您要过滤地图条目还是只过滤每个列表中性别为M 的员工?
  • input.entrySet().stream().filter(entry -> entry.getValue().getGender().equals("M").......
  • 请添加更多细节:过滤器是什么意思(删除/保留有/没有 M 的员工或删除/保留至少有/只有一个员工有/没有 M 的列表)?原图可以修改吗? map.values().forEach(list-&gt;list.removeIf(...)) 还不够吗?添加示例输入和输出以阐明过滤器的含义可能会有所帮助。如果您添加自己想要改进的工作代码会更好。

标签: java java-8 java-stream filtering


【解决方案1】:

员工返回地图

public static Map<Integer, Employee> evaluatemapEmployee()
    {
        //return Dao.getselectedEmployee().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        //return Dao.getselectedEmployee().entrySet().stream().filter(emp->emp.getValue().getsalary()>8000).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        //return Dao.getselectedEmployee().entrySet().stream().filter(emp->emp.getValue().getEmpname().matches("om")).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        //return Dao.getselectedEmployee().entrySet().stream().filter(emp->emp.getValue().getEmpid()==103).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        return Dao.getselectedEmployee().entrySet().stream().filter(emp->emp.getValue().getEmpname().matches("kush")).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }

【讨论】:

    【解决方案2】:

    过滤掉列表中包含不属于"M" 性别的员工的条目

    Map<String, List<Employee>> r2 = map.entrySet().stream()
        .filter(i -> i.getValue().stream().allMatch(e-> "M".equals(e.gender)))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    

    过滤掉不属于"M" 性别的员工

    Map<String, List<Employee>> r1 = map.entrySet().stream()
        .filter(i -> !i.getValue().isEmpty())
        .collect(Collectors.toMap(Map.Entry::getKey,
            i -> i.getValue().stream()
                  .filter(e -> "M".equals(e.gender)).collect(Collectors.toList())));
    

    过滤列表中不包含任何"M" 员工的条目

    Map<String, List<Employee>> r3 = map.entrySet().stream()
        .filter(i -> i.getValue().stream().anyMatch(e -> "M".equals(e.gender)))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    

    让我们在地图中有 2 个条目:

    "1" -> ["M", "M", "M"]
    "2" -> ["M", "F", "M"]
    

    他们的结果将是:

    r1 = {1=[M, M, M], 2=[M, M]}
    r2 = {1=[M, M, M]}
    r3 = {1=[M, M, M], 2=[M, F, M]}
    

    【讨论】:

    • 哈!我怎么会错过这种方法?真是个白痴……再加一个!
    • @Eugene,哪一个? :) allMatch?
    • 这是工作的朋友.. 非常感谢.. 我仍然需要了解过滤器/谓词/收集器的工作机制
    • 我需要在上面的例子中做一个小改动,如果 List 在映射值上为空,我必须删除输出(或过滤映射)中的键
    • @Ranji 这三个选项你选了哪一个?
    【解决方案3】:

    例如:

    Map<String, List<Employee>> result = originalMap.entrySet().stream()
        .filter(es -> es.getValue().stream().anyMatch(emp -> emp.getGender().equals("M")))
        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
    

    【讨论】:

    • 同一种代码,我试过了,但是没用。我总是得到所有的价值
    【解决方案4】:

    仅过滤只有男性员工的地图条目:

    @Test
    public void filterOnlyMales(){
            String gender = "M";
            Map<String, List<Employee>> maleEmployees = map.entrySet()
                     .stream()
                     /*Filter only keys with male Employes*/
                     .filter(entry -> entry.getValue().stream()
                                      .anyMatch(empl -> gender.equals(empl.getGender())))
                     .collect(Collectors.toMap(
                              Map.Entry::getKey,
                              p -> filterMalesOnly(gender, p));
    
        }
    
    private List<Employee> filterMalesOnly(String gender,
                                           Map.Entry<String, List<Employee>> p) {
        return p.getValue()
              .stream()
              .filter(empl -> gender.equals(empl.getGender()))
              .collect(
                      Collectors.toList());
    }
    

    【讨论】:

      【解决方案5】:

      如果条目列表中的任何 Employee 的性别 = M,如果要过滤映射条目,请使用以下代码:

          Map<String,List<Employee>> result = employeeMap.entrySet()
                                      .stream()
                                      .filter(e -> e.getValue()
                                                  .stream()
                                                  .anyMatch(employee -> employee.getGender().equalsIgnoreCase("M")))
                                      .collect(Collectors.toMap(Entry::getKey,Entry::getValue));
      

      而且,如果您想从每个列表中过滤掉所有性别为M 的员工,请使用以下代码:

      Map<String,List<Employee>> result = employeeMap.entrySet()
                             .stream()
                             .collect(Collectors.toMap(Entry::getKey,
                                 e -> e.getValue().stream()
                                 .filter(employee -> employee.getGender().equalsIgnoreCase("M"))
                                 .collect(Collectors.toList())));
      

      【讨论】:

        【解决方案6】:
        Map<String, List<Employee>> result = yourMap.entrySet()
                    .stream()
                    .flatMap(ent -> ent.getValue().stream().map(emp -> new SimpleEntry<>(ent.getKey(), emp)))
                    .filter(ent -> "M".equalsIgnoreCase(ent.getValue().getGender()))
                    .collect(Collectors.groupingBy(
                            Entry::getKey,
                            Collectors.mapping(Entry::getValue, Collectors.toList())));
        

        【讨论】:

          【解决方案7】:

          在 Java 8 中,您可以将 Map.entrySet() 转换为流,然后是 filter()collect()。示例取自 here

              Map<Integer, String> map = new HashMap<>();
              map.put(1, "linode.com");
              map.put(2, "heroku.com");
          
              //Map -> Stream -> Filter -> String
              String result = map.entrySet().stream()
                  .filter(x -> "something".equals(x.getValue()))
                  .map(x->x.getValue())
                  .collect(Collectors.joining());
          
              //Map -> Stream -> Filter -> MAP
              Map<Integer, String> collect = map.entrySet().stream()
                  .filter(x -> x.getKey() == 2)
                  .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
          
              // or like this
              Map<Integer, String> collect = map.entrySet().stream()
                  .filter(x -> x.getKey() == 3)
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
          

          对于您的情况,它看起来像这样,因为您还需要确定在 List 的类 Employee 的对象中是否存在匹配项。

          Map<String, List<Employee>> collect = map.entrySet().stream()
                      .filter(x -> x.getValue().stream()
                  .anyMatch(employee -> employee.Gender.equals("M")))
                      .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
          

          【讨论】:

            猜你喜欢
            • 2019-05-24
            • 2016-10-25
            • 2021-09-03
            • 1970-01-01
            • 1970-01-01
            • 2019-10-01
            • 2018-01-01
            • 2020-02-06
            • 2021-06-07
            相关资源
            最近更新 更多