Java 综合性实验 Java源代码分析程序
題目
Java課程的綜合實(shí)驗(yàn)…大三的時(shí)候?qū)戇^的,不過現(xiàn)在回頭看,發(fā)現(xiàn)寫得真爛,所以在學(xué)習(xí)Java過程中重構(gòu)了代碼.
基本不算重構(gòu)而是重寫…改的時(shí)候差點(diǎn)看不懂自己寫過什么…好了言歸正傳:
實(shí)驗(yàn)的要求如下:
一、題目:綜合性實(shí)驗(yàn) Java源代碼分析程序
二、類型:綜合型、探索型
三、目的:初步掌握運(yùn)用面向?qū)ο蠓椒ň帉憫?yīng)用程序,掌握類、對象、封裝等;了解并應(yīng)用Java語言的字符串處理、文本文件的讀寫
四、內(nèi)容:
1.背景描述:
(1)Java語言共有50個(gè)關(guān)鍵字。
(2)Java源程序是以“.java”為擴(kuò)展名的文本文件。
(3)可以考慮在Java源程序中的行共有3種:
代碼行,可運(yùn)行的Java源代碼。例如:
int n = 10;
注釋行,3種注釋均可。例如:
/**
文檔注釋
*/
/*
多行注釋
/
//單行注釋
空行,既無代碼,也無注釋;
(4)特殊行的處理方法
如果有以下行尾單行注釋的情況,將該行判定為代碼行。
int number; //number表示人數(shù)
int n; /n表示數(shù)量/
如果有以下行尾多行注釋的情況,第1行判定為代碼行,第二行判定為注釋行。
int number; / number為整型
表示人數(shù) */
假設(shè)被分析程序源碼無其他特殊情況,如:
int /人數(shù)/ number;
2. 項(xiàng)目名和類名為JavaCodeAnalyzer,主類名等其他類名自行定義。
實(shí)現(xiàn)功能:
(1) 程序運(yùn)行時(shí)要求輸入一個(gè)目錄的名稱。目錄不存在或不是目錄要提示錯(cuò)誤并重新輸入。
(2) 找出輸入目錄中所有的Java源程序文件(文件擴(kuò)展名為“.java”), 并進(jìn)行源程序文件進(jìn)行分析。
需要分析的結(jié)果有:
目錄中源程序文件個(gè)數(shù)
所有源程序文件總的字節(jié)數(shù)
所有源程序文件中代碼行數(shù)、注釋行數(shù)、空行數(shù)及總行數(shù)。說明:行以回車結(jié)束。
(3) 統(tǒng)計(jì)并按從多到少輸出所有源程序文件中使用的Java關(guān)鍵字及其出現(xiàn)次數(shù)。
(4) 統(tǒng)計(jì)分析的結(jié)果除在屏幕顯示外,還需要存儲到一個(gè)文本文件中,文件內(nèi)容應(yīng)該如下:
目錄名稱:XXXXX(絕對路徑方式)
共有源程序文件XX個(gè),總的大小為:XXXXXX 字節(jié)
源程序文件總行數(shù):xxxx,其中:
代碼行數(shù):xxx,占xx.xx%
注釋行數(shù):xxx,占xx.xx%
空白行數(shù):xxx,占xx.xx%
源程序文件中使用過的關(guān)鍵字有(按使用次數(shù)降序排列):
關(guān)鍵字1:xx次
關(guān)鍵字2:xx次
關(guān)鍵字3:xx次
關(guān)鍵字4:xx次
關(guān)鍵字5:xx次
本次分析時(shí)間:年-月-日,時(shí)-分-秒
注意:統(tǒng)計(jì)關(guān)鍵字使用次數(shù)時(shí),要排除注釋中出現(xiàn)的關(guān)鍵字和字符串直接量中出現(xiàn)的關(guān)鍵字。
好了,總的來說可以分成以下幾個(gè)模塊:
1.判斷輸入目錄是否正確
2.搜索Java文件并保存到ArrayList
3.計(jì)算Java文件個(gè)數(shù)和總大小
4.統(tǒng)計(jì)源文件的代碼行數(shù),注釋行數(shù)等
5.統(tǒng)計(jì)源文件的關(guān)鍵字出現(xiàn)次數(shù)
6.將輸出結(jié)果保存到文件
7.輸出計(jì)算用時(shí)
其中
2,3可以參考我的文章 [Java]統(tǒng)計(jì)指定目錄中文件的個(gè)數(shù)和總的大小
4可以參考[Java]統(tǒng)計(jì)Java源文件代碼行數(shù),注釋行數(shù),空白行數(shù)
5可以參考 [Java]統(tǒng)計(jì)目錄下Java源文件的關(guān)鍵字出現(xiàn)次數(shù)
代碼實(shí)現(xiàn)
※重構(gòu)代碼中對6,7不做實(shí)現(xiàn)
1.判斷輸入目錄是否正確
public static String getPathName() {System.out.println("輸入目錄路徑:");Scanner keyboardInput = new Scanner(System.in);String pathName = null;File root = null;while (true) {pathName = keyboardInput.nextLine();root = new File(pathName);if (root.isFile()) {System.out.println("輸入不是目錄,請重新輸入");} else if (!root.exists()) {System.out.println("目錄不存在,請重新輸入");} else {break;}}return pathName;}2.搜索Java文件并保存到ArrayList
public void searchFiles() {File[] files = root.listFiles();int length = files.length;for (int i = 0; i < length; i++) {if (files[i].isDirectory()) {root = files[i];searchFiles();} else {if (files[i].getName().endsWith(".java"))fileList.add(files[i]);}}}3.計(jì)算Java文件個(gè)數(shù)和總大小
public void countFiles() {long totalSize = 0;System.out.println("目錄名稱:" + fileList.get(0).getParent());System.out.println("文件數(shù):" + fileList.size());for (int i = 0; i < fileList.size(); i++) {totalSize += fileList.get(i).length();}System.out.println("文件總大小(bytes):" + totalSize);}4.統(tǒng)計(jì)源文件的代碼行數(shù),注釋行數(shù)等
代碼與我的文章[Java]統(tǒng)計(jì)Java源文件代碼行數(shù),注釋行數(shù),空白行數(shù)一致.這里僅貼代碼,詳細(xì)解析請參考文章
import java.io.*; import java.util.ArrayList; import java.text.DecimalFormat;public class CodeAnalyzer {public void codeAnalyze(ArrayList<File> fileList) {double rowsCount = 0;double commentsCount = 0;double blanksCount = 0;double codesCount = 0;DecimalFormat df = new DecimalFormat("#.##");for (File file : fileList) {try {rowsCount += countRows(file);blanksCount += countBlanks(file);commentsCount += countComments(file);codesCount = rowsCount - blanksCount - commentsCount;} catch (IOException e) {e.printStackTrace();}}//輸出結(jié)果System.out.println("源程序文件總行數(shù):" + (int) rowsCount);System.out.println("代碼行數(shù):" + (int) codesCount + ",占" + df.format(codesCount / rowsCount * 100) + "%");System.out.println("注釋行數(shù):" + (int) commentsCount + ",占" + df.format(commentsCount / rowsCount * 100) + "%");System.out.println("空白行數(shù):" + (int) blanksCount + ",占" + df.format(blanksCount / rowsCount * 100) + "%");}public int countRows(File file) throws IOException {BufferedReader input = new BufferedReader(new FileReader(file));int rows = 0;while (input.readLine() != null) {rows++;}return rows;}public int countBlanks(File file) throws IOException {BufferedReader input = new BufferedReader(new FileReader(file));int blanks = 0;String line = null;while ((line = input.readLine()) != null) {if (line.trim().equals("")) blanks++;}return blanks;}public int countComments(File file) throws IOException {BufferedReader input = new BufferedReader(new FileReader(file));int comments = 0;String line = null;while ((line = input.readLine()) != null) {line = line.trim();if (line.startsWith("//")) {//單行注釋comments++;} else if (line.startsWith("/*")) { //多行及文檔注釋comments++;while (!line.endsWith("*/")) {line = input.readLine().trim();comments++;}} else if (line.contains("/*")) { //下行尾多行注釋line = input.readLine().trim();if (line.endsWith("*/")) comments++;}}return comments;}}5.統(tǒng)計(jì)源文件的關(guān)鍵字出現(xiàn)次數(shù)
與4一樣,這里僅貼代碼,詳情解析到-> [Java]統(tǒng)計(jì)目錄下Java源文件的關(guān)鍵字出現(xiàn)次數(shù)
import java.io.*; import java.util.*;public class KeywordsAnalyzer {Map keywords;final String[] KEYWORDS = { //50個(gè)關(guān)鍵字"abstract", "assert", "boolean", "break", "byte","case", "catch", "char", "class", "const","continue", "default", "do", "double", "else","enum", "extends", "final", "finally", "float","for", "goto", "if", "implements", "import","instanceof", "int", "interface", "long", "native","new", "package", "private", "protected", "public","return", "strictfp", "short", "static", "super","switch", "synchronized", "this", "throw", "throws","transient", "try", "void", "volatile", "while"};public KeywordsAnalyzer() {keywords = new HashMap();for (String word : KEYWORDS) {keywords.put(word, 0);}}public void keywordsAnalyze(ArrayList<File> fileList) {for (File file : fileList) {try {countKeyWords(file);} catch (IOException e) {e.printStackTrace();}}//排序并輸出結(jié)果List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(keywords.entrySet());Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {@Overridepublic int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {return o2.getValue().compareTo(o1.getValue());}});int count = 0;System.out.println("\n源程序文件中使用過的關(guān)鍵字有(按使用次數(shù)降序排列):");for(int i=0;i<5;i++){System.out.println("關(guān)鍵字 "+list.get(i).getKey()+": "+list.get(i).getValue()+"次");}}public void countKeyWords(File file) throws IOException {BufferedReader input = new BufferedReader(new FileReader(file));String line = null;while ((line = input.readLine()) != null) {line = line.trim();if (line.startsWith("//")) continue; //不處理單行注釋else if (line.contains("/*")) { //多行,文檔與尾行注釋if (!line.startsWith("/*")) matchKeywords(line);//第一行算代碼,其余算注釋while (!line.endsWith("*/")) {line = input.readLine().trim();}}matchKeywords(line); //對代碼行進(jìn)行統(tǒng)計(jì)}}public void matchKeywords(String line) {String[] wordList = line.replaceAll("\\W", " ").split(" ");for (int i = 0; i < wordList.length; i++) {for (int j = 0; j < 50; j++) {if (wordList[i].equals(KEYWORDS[j])) {int count = (int) keywords.get(KEYWORDS[j]);keywords.put(KEYWORDS[j], count + 1);}}}} }測試結(jié)果
測試Timer.java,得到結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的Java 综合性实验 Java源代码分析程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: csapp-深入理解计算机系统学习记录
- 下一篇: 前端学习(1849)vue之电商管理系统