分组依据多个字段的对象列表 Java 8

huangapple go评论73阅读模式
英文:

Group By List of object on multiple fields Java 8

问题

我将拥有一个 Employee 列表,其中将包含 3 个属性 - departmentId、employeeId、employeeGroup。

我想在部门 ID 和员工 ID 上执行分组操作。想法是发送员工所属部门的组名。以下是可能的 3 种情况:

**情况#1:同一部门,不同员工,不同组。**

    ["Dept001", 100, "Admin"]
    ["Dept001", 101, "Contrator"]

**情况#2:同一部门,相同员工,不同组**

    ["Dept001", 100, "Admin"]
    ["Dept001", 100, "Contrator"]

**情况#3:不同部门,不同员工,相同组。**

    ["Dept001", 100, "Admin"]
    ["Dept002", 101, "Admin"]

我尝试了以下内容:

    Map<String, Set<Employee>> map = new TreeMap<>();
    
    map = myList.stream().collect(Collectors.groupingBy(Employee::getDepartmentId, 
    Collectors.toSet()));
英文:

I will have a list of Employee, which will hold 3 attributes - departmentId, employeeId, employeeGroup.

I want to perform group by on Department Id and employee id. The idea is to send the group name of employee with belonging department. Below can be the 3 possible cases:

Case#1: Same department, different employee, different group.

[&quot;Dept001&quot;, 100, &quot;Admin&quot;]
[&quot;Dept001&quot;, 101, &quot;Contrator&quot;]

Case#2: Same department, same employee, different group

[&quot;Dept001&quot;, 100, &quot;Admin&quot;]
[&quot;Dept001&quot;, 100, &quot;Contrator&quot;]

Case#3: Diff department, diff employee, same group.

[&quot;Dept001&quot;, 100, &quot;Admin&quot;]
[&quot;Dept002&quot;, 101, &quot;Admin&quot;]

I have tried below:

Map&lt;String, Set&lt;Employee&gt;&gt; map = new TreeMap&lt;&gt;();

map = myList.stream().collect(Collectors.groupingBy(Employee::getDepartmentId, 
Collectors.toSet()));

答案1

得分: 2

按多个字段分组将需要多次调用Collectors#groupingBy。幸运的是,重载的Collectors#groupingBy方法的第二个参数是另一个Collector,因此可以简单地调用两次。

Map&lt;String, Map&lt;Integer, Set&lt;Employee&gt;&gt;&gt; map = myList.stream()
    .collect(Collectors.groupingBy(Employee::getDepartmentId, 
        Collectors.groupingBy(Employee::getEmployeeId, Collectors.toSet())));

请注意Map的值是另一个Map;第一个Map的键是员工的部门ID,第二个Map的键是员工的员工ID。

英文:

Grouping by multiple fields is going to require multiple calls to Collectors#groupingBy. Luckily, the second parameter of the overloaded Collectors#groupingBy method is another Collector, so it can simply be invoked twice.

Map&lt;String, Map&lt;Integer, Set&lt;Employee&gt;&gt;&gt; map = myList.stream()
    .collect(Collectors.groupingBy(Employee::getDepartmentId, 
        Collectors.groupingBy(Employee::getEmployeeId, Collectors.toSet())));

Note that the value of the Map is another Map; the first of which is keyed with the employees' department ID, and the second is keyed with the employees' employee ID.

答案2

得分: 0

根据我的理解,您只需使用EmployeeIdDepartmentId进行groupBy,以便随后可以使用这个组合属性唯一地标识一个员工。

您可以使用streamTuple结合,代码如下所示:

Map<Tuple, List<Employee>> map = employees.stream()
  .collect(groupingBy(employee -> new Tuple(employee.getEmployeeId(), employee.getDepartmentId())));
英文:

As I understand, you just want to do groupBy with EmployeeId and DepartmentId so that afterward you can uniquely identify an employee with this combined property.

You can use stream combined with Tuple, code will look like this:

Map&lt;Tuple, List&lt;Emplyee&gt;&gt; map = employees.stream()
.collect(groupingBy(employee-&gt; new Tuple(employee.getEmployeeId(), employee.getDepartmentId())));

huangapple
  • 本文由 发表于 2020年4月9日 03:01:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/61108086.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定