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); Listerrs = 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; } } }