【问题标题】:Using Java 8 Streams how to get two different list using one list [duplicate]使用Java 8 Streams如何使用一个列表获取两个不同的列表[重复]
【发布时间】:2019-11-05 23:07:08
【问题描述】:

假设我有员工数据列表。

class Employee {
   private long id;
   private String name;
   private int age;
   // Constrctor
   // setters & getters
}
List<Employee> empList = ...;

使用上面的 empList,如何使用 Java8 流age > 20 等两个不同的列表放入一个列表,将 age 放入一个列表>.

【问题讨论】:

  • 请向我们展示您的努力。到目前为止,您尝试过什么?
  • age = 20 元素会发生什么?

标签: java java-8 java-stream


【解决方案1】:

你可以使用Collectors.partitioningBy

public static void main(String[] args) {
    List<Employee> employeeList = Arrays.asList(new Employee(10), new Employee(15),
            new Employee(21), new Employee(22));

    Map<Boolean, List<Employee>> employeeGroups = employeeList.stream().
                    collect(Collectors.partitioningBy(s -> s.getAge() > 20));

    System.out.println(employeeGroups.get(false));
    System.out.println(employeeGroups.get(true));
}

输出:

[Employee{age=10}, Employee{age=15}]
[Employee{age=21}, Employee{age=22}]

【讨论】:

    【解决方案2】:

    你可以使用Collectors.groupingBy来做到这一点

    Map<Boolean, List<Employee>> ageGtThan20ToEmployees = empList.stream()
                    .collect(Collectors.groupingBy(e -> e.age > 20));
    System.out.println("Employees 20 years old are: "+ageGtThan20ToEmployees.get(true));
    

    【讨论】:

    • 最好使用 boolean-specializedpartitioningBy。不仅是为了效率,还保证geGtThan20ToEmployees.get(true)永远不会是null
    • @Holger 如果我记得正确跟踪了几个链接,那么由于对 Stackoverflow 的讨论而引入了该更改。另外:由于这个问题围绕partitioning,我最近一直想知道为什么在CollectorsPartition 实现中从entrySet() 返回迭代器时需要List.of 而不是Set.of。 (或 JDK-9 之前的 Arrays.asList)。顺序(假,真)真的重要吗?
    • @Naman 的行为总是这样,但文档中没有说明这是故意的,这是在讨论 Stackoverflow 后添加的(一些讨论过的优化仍然缺失)。自然顺序 [false, true] 可能是另一个未记录的故意特征。但这也可能只是性能方面的考虑,因为 Set.of 工厂包含对重复项的检查,这在此处已过时(两个元素的集合和列表迭代器几乎相同)。
    • @Holger 谢谢。这就是我要找的。我尝试在那里寻找迭代器的实现和差异,同时忽略了 Collection 本身的创建。
    【解决方案3】:

    您可以执行以下操作:

    List<Employee> greaterThan20 = empList.filter(e -> e.age > 20).collect(Collectors.toList());
    
    List<Employee> lessThan20 = empList.filter(e -> e.age < 20).collect(Collectors.toList());
    

    【讨论】:

      【解决方案4】:

      我会使用filter 让它变得简单:

      List<Employee> greater20 = empList.stream().filter(employee -> employee.getAge() > 20).collect(Collectors.toList());
      List<Employee> smaller20 = empList.stream().filter(employee -> employee.getAge() < 20).collect(Collectors.toList());
      

      【讨论】:

        猜你喜欢
        • 2019-06-18
        • 2020-07-03
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多