【问题标题】:How can i process the ArrayList with count, and group by function我如何处理带有计数的 ArrayList,并按功能分组
【发布时间】:2019-08-06 18:40:53
【问题描述】:

我正在处理员工的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);

这是我试图获取员工人数的上述代码

int count = 0;
for (Employee e : listEmployee) {
    count++;
}
System.out.println("Count of Employees" + count);

请帮我按部门分组处理数据

我期待以下输出:

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

【问题讨论】:

  • 请给出Employee类的代码

标签: java arraylist hashmap


【解决方案1】:

您可以使用List&lt;Employee&gt; 中的stream() 方法获取Stream&lt;Employee&gt;,并使用Collectors.groupingBy(Employee::getDepartment) 按部门对Employee 对象进行分组。完成后,您将返回一个 Map&lt;String, List&lt;Employee&gt;&gt; 地图对象。

key 将是部门名称,value 将是 Employee 对象的列表,现在我们可以从该员工列表中进一步过滤 不活跃活跃员工:

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

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

【讨论】:

  • 我没有得到想要的结果,而是得到了所有三行
  • @cbrak 通过运行我的代码?我再次运行它,它正在按照预期的结果工作。
  • 如果是布尔类型,我得到了预期的结果
  • @cbrak 所以你把 String status 改成了 boolean status ?我是为前者做的
  • 不,我只是为字符串状态做的,我添加了附件,我做了什么
【解决方案2】:

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

/* 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

改进

如果您的String 处于活动状态,则只能是activeinactive,您应该使用布尔值,并进行这些更改:

//attribute
private boolean active;

//instanciate
new Employee("Kanna", "IT", false);

//count
long active = entry.getValue().stream().filter(Employee::isActive).count();

//getter
public boolean isActive() {
    return active;
}

演示DEMO

【讨论】:

  • 我知道布尔值是最合适的,但由于某种原因,它只是根据我的项目的布尔值
  • @cbrak String 只有你的意思?好的
  • 对不起,输入错误,是的,只有字符串
【解决方案3】:

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

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

遍历 listEmployee 并将所有员工添加到具有唯一部门的哈希图中。

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后,你只需遍历hashmap中每个部门的list,就可以得到不活跃和活跃的学生。

每个部门的列表大小将为您提供该部门的员工总数。为此,您可以使用:

hashMap.get(e.getDepartment()).size()

【讨论】:

    【解决方案4】:

    您可以使用 Map 来解决您的问题。您可以有一个 Map>,它将“Department”作为键,并将属于该部门的所有 Employee 对象作为 value。

    然后您将不得不遍历每个部门的员工列表并计算活跃和非活跃员工。

    【讨论】:

      【解决方案5】:

      这应该可以解决问题...

      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());
      });
      

      【讨论】:

      • 请避免使用“代码转储”的答案,因为虽然它们可能对原始发帖者有所帮助,但它们对本网站的主要目标完全无用:未来用户具有类似问题或问题。问题答案的质量很重要。
      • 至少在你的答案中提供一些体面的文字解释,意思是一两段文字,不作为代码 cmets 埋在代码中。
      猜你喜欢
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      相关资源
      最近更新 更多