Java 如何使用count和group by函数处理ArrayList

Java 如何使用count和group by函数处理ArrayList,java,arraylist,hashmap,Java,Arraylist,Hashmap,我正在处理员工的arraylist,需要按员工数、活动员工数和非活动员工数按功能使用情况分组。我知道如何处理总计,但如何使用group by函数处理arraylist public class Employee { private String name; private String department; private String status; public Employee(String name, String department, String

我正在处理员工的arraylist,需要按员工数、活动员工数和非活动员工数按功能使用情况分组。我知道如何处理总计,但如何使用group by函数处理arraylist

public class Employee {
    private String name;
    private String department;
    private String status;
    public Employee(String name, String department, String status) {
        this.setName(name);
        this.setDepartment(name);
        this.setStatus(status);
    }
    public String getName() {
        return name;
    }
    public String getDepartment() {
        return department;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
}

ArrayList<Employee> listEmployee = new ArrayList<Employee>();
listEmployee.add(new Employee("Ravi", "IT", "active"));
listEmployee.add(new Employee("Tom", "Sales", "inactive"));
listEmployee.add(new Employee("Kanna", "IT", "inactive"));

int count = 0;
for (Employee e : listEmployee) {
    count++;
}
System.out.println("Count of Employees" + count);
请帮助我按部门分组处理数据

我期待以下输出:

部门总活动计数不活动计数
它是211
销售1011

您应该使用
地图
根据部门对员工进行分组,然后为每个部门打印员工人数和活动人数,如下所示

/* for the collector
import static java.util.stream.Collectors.groupingBy;*/

Map<String, List<Employee>> employeePerDep = 
                               listEmployee.stream().collect(groupingBy(Employee::getDepartement));

System.out.printf("%10s %10s %10s %10s\n", "Departement", "total", "active", "inactive");

for (Map.Entry<String, List<Employee>> entry : employeePerDep.entrySet()) {
    int total = entry.getValue().size();
    long active = entry.getValue().stream().filter(e -> e.active.equals("active")).count();
    System.out.printf("%-10s %10d %10s %10s\n", entry.getKey(), total, active, total - active);
}

/* And get : 
Departement      total     active   inactive
Sales               1          0          1
IT                  2          1          1

DEMO

您可以使用
列表中的
流()
方法获取
,并使用
收集器.groupingBy(Employee::getDepartment)
按部门对员工对象进行分组。完成后,您将返回一个
Map
Map对象

键将是部门名称,值将是
员工
对象的列表,现在我们可以从该员工列表中进一步筛选非活动活动员工:

System.out.println("Department total activeCount inactiveCount");
listEmployee.stream().collect(Collectors.groupingBy(Employee::getDepartment)).forEach((dept, emps) -> {
     int count = emps.size();
     long activeCount = emps.stream().filter(e -> "active".equals(e.getActive())).count();
     long inactiveCount = emps.stream().filter(e -> "inactive".equals(e.getActive())).count();
     int i = 12 - dept.length();
     System.out.format(dept + "%" + i +"s" + count + "%10s" + activeCount + "%10s" + inactiveCount, " ", " ", " ");
     System.out.println();
 });
输出:

Department total activeCount inactiveCount
Sales       1          0          1
IT          2          1          1

还建议对活动或非活动状态使用枚举,而不是字符串。

这可能不是最好的方法,但您可以尝试一下。 创建一个以部门为键的HashMap,值将是员工列表

HashMap<String, List<Employee>> hashMap = new HashMap<Integer, List<Employee>>();

这应该可以解决问题

List<Employee> listEmployee = new ArrayList<>();
listEmployee.add(new Employee("Ravi", "IT", "active"));
listEmployee.add(new Employee("Tom", "Sales", "inactive"));
listEmployee.add(new Employee("Kanna", "IT", "inactive"));

Map<String, Map<String, List<Employee>>> result = listEmployee.stream()
                .collect(groupingBy(Employee::getDepartment, groupingBy(Employee::getStatus)));

result.forEach((department, departmentMap) -> {
    System.out.println(department + ", "
          + departmentMap.size() + ", "
          + ofNullable(departmentMap.get("active")).orElse(emptyList()).size() + ", "
          + ofNullable(departmentMap.get("inactive")).orElse(emptyList()).size());
});
List listEmployee=new ArrayList();
添加(新员工(“Ravi”、“IT”、“active”));
添加(新员工(“Tom”、“销售”、“非活跃”);
添加(新员工(“Kanna”、“IT”、“非活跃”);
映射结果=listEmployee.stream()
.collect(groupby(Employee::getDepartment,groupby(Employee::getStatus));
结果。forEach((部门、部门地图)->{
系统输出打印项次(部门+“,”
+departmentMap.size()+“,”
+ofNullable(departmentMap.get(“active”)).orElse(emptyList()).size()+“,”
+ofNullable(departmentMap.get(“非活动”)).orElse(emptyList()).size());
});

您可以使用Map解决您的问题。您可以有一个映射,其中将“部门”作为键,将属于该部门的所有员工对象作为


然后,你必须反复查看每个部门的员工名单,统计在职和非在职员工。

请给出
员工的ghe代码
类请避免“代码转储”回答,因为他们可能会帮助原始海报,它们对于本网站的主要目标(未来有类似问题的用户)仍然毫无用处。问题和答案的质量很重要。至少在回答中提供一些像样的文本解释,意思是一段或两段文本,这些文本不会作为代码注释隐藏在代码中。我知道布尔值最合适,但出于某种原因,它仅根据我的理解是布尔值project@cbrak
String
只有你的意思?对不起,输入错误,是的,它的字符串我没有得到想要的结果,而是我得到了所有三个rows@cbrak通过运行我的代码?我再次运行它,它按照预期的结果工作。如果它是布尔类型,我将得到预期的结果result@cbrak所以您将
字符串状态
更改为
布尔状态
?我是为表单做的,我只是为字符串状态做的,我添加了附件,我做了什么
HashMap<String, List<Employee>> hashMap = new HashMap<Integer, List<Employee>>();
if (!hashMap.containsKey(e.getDepartment())) {
    List<Employee> list = new ArrayList<Employee>();
    list.add(e);

    hashMap.put(e.getDepartment(), list);
} else {
    hashMap.get(e.getDepartment()).add(e);
}
hashMap.get(e.getDepartment()).size()
List<Employee> listEmployee = new ArrayList<>();
listEmployee.add(new Employee("Ravi", "IT", "active"));
listEmployee.add(new Employee("Tom", "Sales", "inactive"));
listEmployee.add(new Employee("Kanna", "IT", "inactive"));

Map<String, Map<String, List<Employee>>> result = listEmployee.stream()
                .collect(groupingBy(Employee::getDepartment, groupingBy(Employee::getStatus)));

result.forEach((department, departmentMap) -> {
    System.out.println(department + ", "
          + departmentMap.size() + ", "
          + ofNullable(departmentMap.get("active")).orElse(emptyList()).size() + ", "
          + ofNullable(departmentMap.get("inactive")).orElse(emptyList()).size());
});