Java机试题: 简单错误记录


描述

开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。

处理:

1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是“相同”的错误记录。 2、 超过16个字符的文件名称,只记录文件的最后有效16个字符; 3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录 4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准

示例1

输入:
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
输出:
rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2
说明:
由于D:\cfmwafhhgeyawnool 649的文件名长度超过了16个字符,达到了17,所以第一个字符'c'应该被忽略。
记录F:\fop\ywzqaop 631和F:\yay\jc\ywzqaop 631由于文件名和行号相同,因此被视为同一个错误记录,哪怕它们的路径是不同的。
由于循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准,所以D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645不会被记录。 

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List errs = new ArrayList();
        int order = 0;
        List errsRet =  new ArrayList();
        while(sc.hasNextLine()){
            // 错误日志持续记录,并且设置编号
            order++;
            String[] strs = sc.nextLine().split(" ");
            Error err = new Error();
            err.setOrder(order);
            err.setUrl(strs[0]);
            err.setLine(strs[1]);
            // 文件名
            String fileName = "";
            if(strs[0].indexOf("\\") > -1){
                String[] temp  = strs[0].split("\\\\");
                fileName = temp[temp.length -1];
            } else {
                fileName = strs[0];
            }
            // 文件名超过长度16的处理
            if(fileName.length() > 16){
                fileName = fileName.substring(fileName.length() - 16,fileName.length());
            }
            err.setFileName(fileName);
            errs.add(err);
            // 重置结果集合
            errsRet =  new ArrayList();
        }
        // 根据fileName和行号分组,重复的求和处理
        Map> maps = errs.stream().collect(Collectors.groupingBy(o->o.getFileName() + o.getLine()));
        for (Map.Entry> entry : maps.entrySet()) {
            Error temp = new Error();
            List tempList = entry.getValue();
            temp.setNum(tempList.size());
            // 重复的编号,按照首次出现的算
            Error minOderErr =  tempList.stream().min((o1,o2) ->{
                return o1.getOrder() - o2.getOrder();
            }).orElse(null);
            temp.setOrder(minOderErr.getOrder());
            temp.setLine(minOderErr.getLine());
            temp.setUrl(minOderErr.getUrl());
            temp.setFileName(minOderErr.getFileName());
            errsRet.add(temp);
        }
        // 统计结果按照编号倒序,取最新的8个(因为最多只输出最新的8个统计结果)
        errsRet = errsRet.stream().sorted((o1, o2) -> {
            return o2.getOrder() - o1.getOrder();
        }).collect(Collectors.toList());
        // 输出时,又需要按照编号小到大顺序输出8行统计结果
        List errsFinallRet =  new ArrayList();
        int errCount = 0;
        for (int i = 0; i < errsRet.size(); i++) {
            errCount++;
            if(errCount > 8){
                break;
            } else{
                errsFinallRet.add(errsRet.get(i));
            }
        }
        errsFinallRet = errsFinallRet.stream().sorted((o1, o2) -> {
            return o1.getOrder() - o2.getOrder();
        }).collect(Collectors.toList());
        // 输出结果
        int count = 0;
        Error curErr = new Error();
        for (int i = 0; i < errsFinallRet.size(); i++) {
            curErr = errsFinallRet.get(i);
            count++;
            if(count > 8){
                break;
            }
            System.out.println(curErr.getFileName() + " " + curErr.getLine() + " " + curErr.getNum());
        }
    }

    public static class Error {
        private int order; // 序号
        private String url; // 路径
        private String fileName; // 文件名称
        private String line; // 行号
        private int num; // 错误个数

        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        public int getOrder() {
            return order;
        }

        public void setOrder(int order) {
            this.order = order;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getFileName() {
            return fileName;
        }

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

        public String getLine() {
            return line;
        }

        public void setLine(String line) {
            this.line = line;
        }
    }
}