需要在 java 中打印如下格式的排序地图值

Need to print sorted map value like below format in java

我正在通过对员工编号和员工薪水进行分组来对员工数据进行排序。我得到了异常输出,但我需要将此详细信息存储在固定长度的文件中。所以我需要按以下格式打印。

public class SortData {

    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
                      new Employee("102", "300", "100", "200"),
                      new Employee("101", "200", "80", "120"),
                      new Employee("102", "100", "50", "50"), 
                      new Employee("103", "300", "100", "200"),
                      new Employee("101", "200", "80", "120"),
                      new Employee("101", "100", "50", "50"));

        
        Map<String, Map<String, List<Employee>>> map = employees.stream()
                  .collect(Collectors.groupingBy(Employee::getEmpNo, 
    Collectors.groupingBy(Employee::getEmpSal)));
        
        System.out.println(map);
    }

}



class Employee {

    private String empNo;
    private String empSal;
    private String empHra;
    private String empPf;

    // getter
    // setter

  }

以上代码输出结果如下

{101={100=[Employee(empNo=101, empSal=100, empHra=50, empPf=50)], 200=[Employee(empNo=101, 
  empSal=200, empHra=80, empPf=120), Employee(empNo=101, empSal=200, empHra=80, empPf=120)]}, 
  102={100=[Employee(empNo=102, empSal=100, empHra=50, empPf=50)], 300=[Employee(empNo=102, 
  empSal=300, empHra=100, empPf=200)]}, 
  103={300=[Employee(empNo=103, empSal=300, empHra=100, empPf=200)]}}

我需要把它打印出来放在一个固定长度的文件中。所以我需要如下输出。

1011005050
10120080120
10120080120
1021005050
102300100200
103300100200

谁能帮我解决这个问题。

首先,当前实现中的地图未排序。

其次,对地图进行排序可能是多余的。似乎为了打印输入数据,只需要按 empNoempSal:

对输入列表进行排序
Comparator<Employee> sortByNoAndSal = Comparator
        .comparing(Employee::getEmpNo)
        .thenComparing(Employee::getEmpSal);

employees.sort(sortByNoAndSal);

最后,print/output 应实现 Employee 特定方法的实例(通过覆盖 Employee::toString,或创建特定方法)。旁注 - 所需输出似乎缺少 Employee.

字段之间的分隔符
// class PrintData
public static void printEmployee(Employee emp) {
    String delimiter = ""; // fix if necessary
    System.out.println(String.join(delimiter, emp.getNo(), emp.getSal(), emp.getHra(), emp.getPf()));
}

// invoke this method
employees.forEach(PrintData::printEmployee);

您可以使用:

List<String> result = employees.stream()
            .collect(Collectors.groupingBy(Employee::getEmpNo, Collectors.groupingBy(Employee::getEmpSal)))
            .values()
            .stream()
            .flatMap(e -> buildOutput(e).stream())
            .collect(Collectors.toList());



private List<String> buildOutput(Map<String, List<Employee>> entry) {
    return entry.entrySet().stream()
            .flatMap(e -> e.getValue().stream().map(this::buildOutputForEmployee))
            .collect(Collectors.toList());
}

private String buildOutputForEmployee(Employee em) {
    return String.format("%s%s%s%s", em.getEmpNo(), em.getEmpSal(), em.getEmpHra(), em.getEmpPf());
}

打印结果:

    result.forEach(System.out::println);

输出:

1011005050
10120080120
10120080120
1021005050
102300100200
103300100200

根据您的评论,您希望按 员工编号 排序,然后按 员工薪水 排序。

目前,您没有排序,而是依赖于从 groupingBy 操作返回的地图类型的默认排序。

1.分组时使用 TreeMap

您可以通过传递 Supplier 参数指定要用于 groupingBy 的地图类型。不幸的是,在这种情况下,您还必须通过收集器 (toList())。

 Map<String, Map<String, List<Employee>>> map = employees.stream()
            .collect(Collectors.groupingBy(Employee::getEmpNo,
                    () -> new TreeMap<>(Comparator.comparingInt(Integer::valueOf)),
                    Collectors.groupingBy(Employee::getEmpSal,
                            () -> new TreeMap<>(Comparator.comparingInt(Integer::valueOf)),
                            Collectors.toList())));

我正在使用比较器按 TreeMap1 中员工编号和薪水的 整数值 排序。

您可以将其打印为(在您的情况下,您会将每条记录写入一个文件)。

map.entrySet()
        .stream()
        .flatMap(entry -> entry.getValue().entrySet().stream())
        .flatMap(innerEntry -> innerEntry.getValue().stream())
        .forEach(emp -> System.out.println(buildRecord(emp)));

其中 buildRecord 只是连接了 Employee class 的字段。

private static String buildRecord(Employee employee) {
    return new StringBuilder()
            .append(employee.getEmpNo())
            .append(employee.getEmpSal())
            .append(employee.getEmpHra())
            .append(employee.getEmpPf())
            .toString();
}

2。排序列表

但是不需要对复杂的数据结构进行分组操作。您可以简单地使用比较器对其进行排序。

employees.sort(Comparator.<Employee>comparingInt(emp -> Integer.parseInt(emp.getEmpNo()))
            .thenComparingInt(emp -> Integer.parseInt(emp.getEmpSal())));

这将按雇员 id/number 然后按工资 1.

对雇员列表进行排序

打印为,

employees.forEach(employee -> System.out.println(buildRecord(employee)));

1 - 这假设员工人数和薪水是整数。您可以根据需要进行更改。