【问题标题】:Filter map and return list of keys过滤映射并返回键列表
【发布时间】:2020-04-05 11:17:48
【问题描述】:

我们有一个Map<String, Student> studentMap,其中Student 是一个类,如下所示:

class Student{
    String name;
    int age;
}

我们需要返回一个包含所有 ID eligibleStudents 的列表,其中年龄 > 20。
为什么在Collectors.toList下面会出现编译错误:

HashMap<String, Student> studentMap = getStudentMap();
eligibleStudents = studentMap .entrySet().stream()
        .filter(a -> a.getValue().getAge() > 20)
        .collect(Collectors.toList(Entry::getKey));

【问题讨论】:

    标签: java list dictionary java-8 java-stream


    【解决方案1】:

    Collectors.toList()不带任何参数,你需要先map它:

    eligibleStudents = studentMap.entrySet().stream()
        .filter(a -> a.getValue().getAge() > 20)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
    

    【讨论】:

      【解决方案2】:

      toList()collector 只是创建一个容器来收集元素并且不接受任何参数。您需要在收集之前进行映射。这是它的外观。

      List<String> eligibleStudents = studentMap.entrySet().stream()
          .filter(a -> a.getValue().getAge() > 20)
          .map(Map.Entry::getKey)
          .collect(Collectors.toList());
      

      【讨论】:

        【解决方案3】:

        filter 之后,您将获得Student 类型的流。对于过滤流中的每个学生,您需要他/她的年龄。因此,您必须对学生和他/她的年龄进行一对一的映射。使用map 运算符:

        HashMap<String, Student> studentMap = getStudentMap();
                    eligibleStudents = studentMap .entrySet().stream()
                            .filter(a->a.getValue().getAge()>20)
                            .map(a -> a.getKey())
                            .collect(Collectors.toList());
        

        【讨论】:

          【解决方案4】:

          您的解决方案中的问题是 Collectors.toList() 方法不带任何参数。请参阅下面的定义。

          public static &lt;T&gt; Collector&lt;T,?,List&lt;T&gt;&gt; toList()

          过滤操作后你会得到streamEntry&lt;Id, Student&gt;。 所以你必须将Entry&lt;Id, Student&gt; 转换为Id。 在以下解决方案中的 ma​​p 操作之后,您将拥有 Idstream。 然后进行Ids的收集。

          HashMap<String, Student> studentMap = getStudentMap();
          List<Id> eligibleStudentIds = studentMap.entrySet().stream()
                      .filter(s -> s.getValue().getAge()>20)
                      .map(a -> a.getKey())
                      .collect(Collectors.toList());
          

          【讨论】:

            【解决方案5】:

            我总是建议尝试调试您在终端操作后得到的结果。

            Intellij Alt+Ctrl+V 中有一个功能可以告诉您手术后左侧的情况。

            示例

            当你有以下代码时:

            studentMap .entrySet().stream()
                    .filter(a -> a.getValue().getAge() > 20)
                    .collect(Collectors.toList());
            

            当你全选并按下Alt+Ctrl+V 然后你会发现这个代码块返回List&lt;Map.Entry&lt;String,Integer&gt;&gt;

            所以现在你知道你的 return 不是 String 的 List,你现在需要筛选其他东西,只接受更多的 String,为此你需要使用 map

            只要你像下面的代码sn-p那样映射:

            studentMap .entrySet().stream()
                                .filter(a->a.getValue().getAge()>20)
                                .map(a -> a.getKey())
                                .collect(Collectors.toList());
            

            现在,当您选择整个代码 sn-p 并按 Alt+Ctrl+V 时,您会知道现在您得到了您之前想要的实际返回,即 List&lt;String&gt;

            希望它在接下来的编码工作中对您有所帮助。

            【讨论】:

              猜你喜欢
              • 2021-08-13
              • 2018-09-26
              • 1970-01-01
              • 2022-12-07
              • 2023-02-22
              • 2018-08-22
              • 2016-09-27
              • 2019-08-20
              • 1970-01-01
              相关资源
              最近更新 更多