首先创建记录错误记录信息的"Record"类

class Record implements Comparable {

    private String fileName;
    private String row;
    private int count;
    private int pos;

    ....
}
  1. fileName字段为文件名:对于输入的文件名称,使用"split"函数分割得到文件名(不包含路径),这也是为了方便“文件所在的目录不同,文件名和行号相同”的合并操作。
  2. row字段为行号,记录输入的行号。
  3. count字段为这类错误记录发生的次数。
  4. pos字段为错误记录的序号,主要是为了之后的排序(数目相同的情况下,按照输入出现顺序排序)。

  通过题意,可以得到错误记录可以通过“文件名+行号”来唯一区分,对应于Record类,就是由字段"fileName+row"可以区分不同的错误记录。因此,我们需要重写Record类中的"equals"和"hashcode"方法。在统计不同错误记录的次数时,我们使用HashMap进行统计。

  此外,为了后续使用"Arrays.sort()"方法进行排序,Record类还实现了"Comparable"接口,并且定义降序排序规则。最后,在输出的时候,需要注意如果文件名长度超过16位,只需输出后16位。

代码如下:

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

class Record implements Comparable {

    private String fileName;
    private String row;
    private int count;
    private int pos;

    public Record(String fileName, String row) {
        this.fileName = fileName;
        this.row = row;
    }

    public int getPos() {
        return pos;
    }

    public void setPos(int pos) {
        this.pos = pos;
    }

    public String getFileName() {
        return fileName;
    }

    public String getRow() {
        return row;
    }

    public int getCount() {
        return count;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void setRow(String row) {
        this.row = row;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public int compareTo(Object o) {
        Record record = (Record) o;
        return record.count - this.count;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else {
            Record record = (Record) obj;
            if (this.fileName.equals(record.getFileName()) && this.row.equals(record.getRow())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.fileName.hashCode() + this.row.hashCode();
    }


    @Override
    public String toString() {
        String fileName = this.fileName;
        if (fileName.length() > 16) {
            fileName = fileName.substring(this.fileName.length() - 16);
        }
        return fileName + " " + this.row + " " + this.count;
    }
}

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Map<Record, Integer> errorCount = new HashMap<Record, Integer>();

        int pos = 0;
        while (scanner.hasNext()) {
            String errorInfo = scanner.nextLine();
            String[] errorInfos = errorInfo.split(" ");
            String[] paths = errorInfos[0].split("\\\\");
            Record record = new Record(paths[paths.length - 1], errorInfos[1]);
            if (!errorCount.containsKey(record)) {
                record.setPos(pos++);
                errorCount.put(record, 0);
            }
            errorCount.put(record, errorCount.get(record) + 1);
        }
        scanner.close();

        Record[] records = new Record[errorCount.size()];
        for (Record record : errorCount.keySet()) {
            record.setCount(errorCount.get(record));
            records[record.getPos()] = record;
        }

        Arrays.sort(records);

        for (int i = 0; i < 8 && i < records.length; i++) {
            System.out.println(records[i]);
        }

    }

}