Java综合实验 Java源代码注释及关键字分析程序

一、题目介绍与分析

编写一个Java应用程序,对单个Java源程序文件及某个目录中的所有Java源程序文件(包括子目录)进行分析,分析内容包括:

1)Java源程序文件个数,对目录分析进行分析时需要。

2)Java源程序中的字符个数,对目录分析时是其中所有源程序文件的字符个数总和。

3)Java源程序文件中的注释的个数,即源程序文件中共有多少个注释,包括:单行注释和多行注释。对目录分析时是其中所有源程序文件的总和。

4)Java源程序文件中的注释的字符个数,即源程序文件中所有注释的字符数之和。对目录分析时是其中所有源程序文件的总和。

5)Java源程序文件中关键字使用情况,即源程序文件各个关键字使用了多少次。对目录分析时是其中所有源程序文件的总和。


具体要求如下

  1. 程序运行首先显示所示的菜单
    ---------------- MENU -------------
    1.分析目录或者源程序文件
    2.查看已有的分析结果
    0.退出
    ----------------------------------------
    请选择:

  1. 选择菜单项目1时,首先要求输入要分析的目录名或Java源程序文件名。

    1)如果输入的目录或文件名不存在,提示不存在;输入的文件名的扩展名不是“.java”时提示不是Java源程序文件。

    2)如果输入的是一个Java源程序文件名,对该源程序文件进行分析。

    3)如果输入的是一个目录名,对该目录中所有的源程序文件进行分析。

    4)分析的结果存储到一个文本文件中,在当前目录中建立一个data目录,结果文件放在data目录中。

    分析目录时结果文件名:D_目录名_Result.txt,例如:D_lang_Result.txt

    分析源程序文件时结果文件名:F_源程序文件名_Result.txt,例如:F_String.java_Result.txt

    5)结果文件中内容的格式

    第1行:分析目录 : C:Program\Files\Java\jdk1.8.0_31\src\java

    第2行:空行

    第3行:Java源程序文件个数: 1866 (分析文件时无此行)

    第4行:源程序中字符总个数 : 29022541

    第5行:注释总个数 : 57349

    第6行:注释总的字符数 : 17559371

    第7行:空行

    第8行:关键字使用情况如下:

    第9行:[int = 27705] (从第9行开始输出各个关键字及其使用的次数,每行一个)

    说明:

    分析结束时,不显示分析结果,结果存储到文本文件,显示如下提示:

    目录分析结束, 分析结果存放在文件[data/D_util_Result.txt]!

    或者:

    文件分析结束, 分析结果存放在文件[data/F_String.java_Result.txt]!

    关键字输出时,按使用次数从大到小排序,次数相同时,按字母顺序排序。

    Java语言的所有关键字

public static final String[] KEYWORDS = { "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", "short", "static", 
 "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", 
 "volatile", "while" }; 



  1. 查看已有的分析结果要求

    选择菜单项目2时,首先列出已经分析并存储的结果,如下:
    -----------------------------------
    1–D_test.java_Result.txt
    2–D_test2.java_Result.txt
    ------------------------------------
    输入要查看的文件编号:

    即列出data目录中存储的所有分析结果文件,并给出一个序号

    输入要查看的文件序号后,显示该文件中的内容。例如下:
    ------------------------------------------------------------------------------------------------------
    分析目录: D:\Java\Java实验题\Comprehensive\test.java

    Java源程序文件个数 :5
    源程序中字符总个数 :9432
    注释总个数 :59
    注释总的字符数 :2361

    关键字的使用情况如下:
    [public = 32]
    [return = 14]
    [static = 14]
    [double = 12]
    [if = 10]
    [private = 10]
    [this = 10]
    [void = 10]
    [int = 8]
    [new = 8]
    [char = 5]
    [class = 5]
    [for = 5]
    [package = 5]
    [boolean = 4]
    [final = 4]
    [import = 4]
    [while = 2]
    [break = 1]
    [else = 1]
    ----------------------------------------------------------------------------------------------



二、相关提示
  1. 分析注释个数和注释的字符数时,假设没有注释嵌套的问题。即测试用的文件和目录中没有如下情况:

    /** //注释1 */

    // 注释2 /* */

  2. 分析注释个数和注释的字符数时,假设字符串直接量中没有注释形式,即没有下面的情况:

    String s = “/abcd/”;

  3. 分析关键字使用次数时,注意以下几种情况不能计算关键字个数:

    (1) 注释中出现的关键字,例如下面的int不能计数

    /**

    * int k=0;

    */

    (2) 字符串直接量中的关键字,例如下面的int不能计数

     System.out.println(“input a int: ”); 
    

    (3) 注意整字识别,例如 println 中的int不是关键字,不能计数。

  4. 如果使用正则表达式进行编程,除基本的正则表达式使用外,可以参考Java的如下两个类:

    java.util.regex.Pattern

    java.util.regex.Matcher

三、源码

0. 注意事项
1. 项目结构
2. 各个类的信息
3. 源代码
4. 项目Gitee地址



0. 注意事项

测试数据不要太大!!!!!()博主很懒,没进行优化😥。
可以使用项目test.java目录中提供的数据。



1. 项目结构

在这里插入图片描述





2. 各个类的介绍

在这里插入图片描述





3. 运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述





源代码

Functions类

package cn.zg.frame;

import cn.zg.module.Comment;
import cn.zg.module.Keyword;
import cn.zg.module.LookUpFile;
import cn.zg.module.SaveFile;
import cn.zg.utils.*;

import java.io.File;
import java.util.Objects;
import java.util.Scanner;


/**
 * @author zg
 */
public class Functions {

    public static final String JAVA_SUFFIX = ".java";

    /**
     * 功能1:分析目录或者源程序文件
     */
    public static void evaluate() {
        String input = new Scanner(System.in).next();
        System.out.println();
        File file = new File(input);
        if (!file.exists()) {
            //  目录或文件名不存在
            System.out.print("输入的目录或文件名不存在,请重新选择:");
            evaluate();
        } else if (file.isDirectory()) {
            //  目录
            dirEvaluate(input);
        } else {
            //  文件
            if (!input.toLowerCase().endsWith(JAVA_SUFFIX)) {
                //  不是以.java结尾的文件
                System.out.print("您输入的不是Java源程序文件,请重新输入:");
                evaluate();
            }
            fileEvaluate(input);
        }
    }

    /**
     * 分析目录
     *
     * @param dir 目录名
     */
    public static void dirEvaluate(String dir) {
        System.out.println("分析目录          :" + dir);
        System.out.println();
        System.out.println("Java源程序文件个数 :" + String.format("%10d", JavaFileCountUtil.javaFileCount(dir)));
        System.out.println("源程序中字符总个数 :" + String.format("%10d", InTotalCharsUtil.dirCharsCount(dir)));
        System.out.println("注释总个数        :" + String.format("%10d", Comment.dirCommentCounts(dir)));
        System.out.println("注释总的字符数     :" + String.format("%10d", Comment.dirCommentChars(dir)));
        System.out.println();
        System.out.println("关键字的使用情况如下:");
        //  打印关键字的使用情况
        Keyword.print(dir);
        //  保存分析结果
        SaveFile.saveDir(dir);
    }

    /**
     * Java源程序分析
     *
     * @param file 文件名
     */
    public static void fileEvaluate(String file) {
        System.out.println("分析文件           :" + file);
        System.out.println();
        System.out.println("源程序中字符总个数  :" + String.format("%10d", InTotalCharsUtil.javaCharsCount(file)));
        System.out.println("注释总个数        :" + String.format("%10d", Comment.fileCommentCounts(file)));
        System.out.println("注释总的字符数     :" + String.format("%10d", Comment.fileCommentChars(file)));
        System.out.println();
        System.out.println("关键字的使用情况如下:");
        //  打印关键字的使用情况
        Keyword.print(file);
        //  保存分析结果
        SaveFile.saveFile(file);
    }


    /**
     * 功能2:查看已分析的结果
     */
    public static void lookUp() {
        File file = new File("src\\data");
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                //  如果有分析结果
                System.out.println("-----------------------------------");
                for (File f : files) {
                    System.out.println(f.getName());
                }
                System.out.println("------------------------------------");
            } else {
                //  如果没有分析结果
                System.out.print("目前还未进行文件或者目录的分析,请选择其他功能:");
                Start.function();
            }

            System.out.print("输入要查看的文件编号:");
            int input = new Scanner(System.in).nextInt();
            if (input < 1 || input > Objects.requireNonNull(files).length) {
                System.out.print("输入的文件编号有误,请重新输入文件编号:");
                input = new Scanner(System.in).nextInt();
                System.out.println();
                System.out.println();
                System.out.println();
            }
            System.out.println();
            System.out.println();
            if (files != null) {
                //  查看具体的分析结果
                LookUpFile.lookUp(files[input - 1].getAbsolutePath());
            }

        }
    }

}



初始界面Start类

package cn.zg.frame;

import java.util.Scanner;

import static cn.zg.frame.Functions.evaluate;
import static cn.zg.frame.Functions.lookUp;

/**
 * @author zg
 */
public class Start {

    /**
     * 功能1的选择:分析目录或者文件
     */
    public static final int EVALUATE_DIR_OR_FILE = 1;
    /**
     * 功能2的选择:查看已分析结果
     */
    public static final int LOOK_UP_RESULT = 2;
    /**
     * 退出的选择
     */
    public static final int EXIT = 0;

    /**
     * 菜单
     */
    public static void mainFrame() {
        System.out.println("-----------MENU-----------");
        System.out.println("  1.分析目录或者源程序文件    ");
        System.out.println("  2.查看已有的分析结果       ");
        System.out.println("  0.退出                   ");
        System.out.println("--------------------------");
        System.out.print(" 请选择:");
        function();
    }

    /**
     * 选择菜单中的功能
     */
    public static void function() {
        int input = new Scanner(System.in).nextInt();
        if (input == EVALUATE_DIR_OR_FILE) {
            System.out.print("请输入要分析的目录名或Java源程序文件名:");
            //  功能1:分析目录或者源程序文件
            evaluate();
        } else if (input == LOOK_UP_RESULT) {
            System.out.println();
            System.out.println();
            // 查看已分析的结果
            lookUp();
            System.out.println();
            System.out.println();
        } else if (input == EXIT) {
            System.exit(0);
        } else {
            mainFrame();
        }
    }
}



Main

package cn.zg.main;

import cn.zg.frame.Start;

/**
 * @author zg
 */
public class Main {
    public static void main(String[] args) {
        Start.mainFrame();
    }
}


Comment类

package cn.zg.module;

import cn.zg.utils.CommentCountsAndCharsUtil;
import cn.zg.utils.TextIntoListUtil;

import java.io.File;
import java.util.ArrayList;

/**
 * @author zg
 */
public class Comment {

    /**
     * @param filePath 文件的路径
     * @return 文件的注释个数
     */
    public static long fileCommentCounts(String filePath) {
        //  把文件存进数组中
        ArrayList<String> list = TextIntoListUtil.fileList(filePath);
        long[] countsAndChars = CommentCountsAndCharsUtil.operateNote(list);
        return countsAndChars[0];
    }

    /**
     * @param filePath 文件的路径
     * @return 文件的注释的字符数
     */
    public static long fileCommentChars(String filePath) {
        ArrayList<String> list = TextIntoListUtil.fileList(filePath);
        long[] countsAndChars = CommentCountsAndCharsUtil.operateNote(list);
        return countsAndChars[1];
    }

    /**
     * @param dirPath 目录的路径
     * @return 目录中所有java文件的注释个数
     */
    public static long dirCommentCounts(String dirPath) {
        long count = 0;
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return 0;
        }
        for (File f : files) {
            if (f.isFile()) {
                count += fileCommentCounts(f.getAbsolutePath());
            } else {
                count += dirCommentCounts(f.getAbsolutePath());
            }
        }
        return count;
    }

    /**
     * @param dirPath 目录的路径
     * @return 目录中所有java文件的注释个数
     */
    public static long dirCommentChars(String dirPath) {
        long count = 0;
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return 0;
        }
        for (File f : files) {
            if (f.isFile()) {
                count += fileCommentChars(f.getAbsolutePath());
            } else {
                count += dirCommentChars(f.getAbsolutePath());
            }
        }
        return count;
    }
}


FileID类

package cn.zg.module;

import java.io.Serializable;

/**
 * @author zg
 */
public class FileID implements Serializable {

    /**
     * 无论类怎么改都不会生成新的序列化ID
     */
    private static final long serialVersionUID = 1L;

    private int id;

    public FileID() {
    }

    public FileID(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}


Keyword类

package cn.zg.module;

import cn.zg.utils.KeySelectUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author zg
 */
public class Keyword {

    /**
     * @param fileName 文件路径
     * @return 把关键字使用情况的结果存进文件中
     */
    public static ArrayList<String> writeIntoFile(String fileName) {
        File file = new File(fileName);
        ArrayList<String> returnList = new ArrayList<>();
        Map<String, Integer> map;
        if (file.isFile()) {
            map = KeySelectUtil.fileCountKeyWords(fileName);
        } else {
            map = KeySelectUtil.dirCountKeyWords(fileName);
        }
        List<Map.Entry<String, Integer>> list = null;
        if (map != null) {
            list = KeySelectUtil.mapIntoListAndSort(map);
        }
        if (list != null) {
            for (Map.Entry<String, Integer> stringIntegerEntry : list) {
                if (stringIntegerEntry.getValue() > 0) {
                    returnList.add("[" + String.format("%-15s", stringIntegerEntry.getKey()) +
                            "=" + String.format("%5d", stringIntegerEntry.getValue()) + "]");
                }
            }
        }
        return returnList;
    }

    /**
     * @param fileName 文件路径
     *                 打印关键字使用情况的结果
     */
    public static void print(String fileName) {
        File file = new File(fileName);
        Map<String, Integer> map;
        if (file.isFile()) {
            map = KeySelectUtil.fileCountKeyWords(fileName);
        } else {
            map = KeySelectUtil.dirCountKeyWords(fileName);
        }
        List<Map.Entry<String, Integer>> list = null;
        if (map != null) {
            list = KeySelectUtil.mapIntoListAndSort(map);
        }
        if (list != null) {
            for (Map.Entry<String, Integer> stringIntegerEntry : list) {
                if (stringIntegerEntry.getValue() > 0) {
                    System.out.println("[" + String.format("%-15s", stringIntegerEntry.getKey()) +
                            "=" + String.format("%5d", stringIntegerEntry.getValue()) + "]");
                }
            }
        }
    }
}


LookUpFile类

package cn.zg.module;

import cn.zg.frame.Functions;
import cn.zg.frame.Start;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

/**
 * @author zg
 */
public class LookUpFile {
    /**
     * @param absolutePath 存储关键字文件的路径
     *                     读取数据文件
     */
    public static void lookUp(String absolutePath) {
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(absolutePath))) {
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();
        System.out.println();
        System.out.print("返回主菜单请输入1,返回上一层请输入2,退出请输入0:");
        boolean loop = true;

        while (loop) {
            int input = new Scanner(System.in).nextInt();
            if (input == 1) {
                System.out.println();
                System.out.println();
                Start.mainFrame();
                loop = false;
            } else if (input == 0) {
                loop = false;
                System.exit(0);
            } else if (input == 2) {
                System.out.println();
                System.out.println();
                Functions.lookUp();
            } else {
                System.out.print("输入有误!请重新输入!返回主菜单请输入1,返回上一层请输入2,退出请输入0:");
            }
        }
    }
}


SaveFile类

package cn.zg.module;

import cn.zg.utils.InTotalCharsUtil;
import cn.zg.utils.JavaFileCountUtil;
import cn.zg.utils.OtherUtils;

import java.io.*;
import java.util.ArrayList;

/**
 * @author zg
 */
public class SaveFile {

    /**
     * 从id的序列化文件读取id
     *
     * @return id
     */
    public static int getId() {
        int id = 0;
        try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src\\id\\id.txt"))) {
            FileID obj = (FileID) objectInputStream.readObject();
            id = obj.getId();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return id;
    }

    /**
     * 更新id
     *
     * @param id 原id
     */
    public static void setId(int id) {
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("src\\id\\id.txt"))) {
            objectOutputStream.writeObject(new FileID(id));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 存储目录的分析结果
     *
     * @param dirPath 目录名
     */
    public static void saveDir(String dirPath) {
        int id = getId();
        id++;
        setId(id);
        File file = new File(dirPath);
        String path = "" + id + "--D_" + file.getName() + "_Result.txt";
        try (final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("src\\data\\" + path))) {
            String[] strings = {
                    "------------------------------------------------",
                    "分析目录          :" + dirPath,
                    "Java源程序文件个数 :" + JavaFileCountUtil.javaFileCount(dirPath),
                    "源程序中字符总个数 :" + InTotalCharsUtil.dirCharsCount(dirPath),
                    "注释总个数        :" + Comment.dirCommentCounts(dirPath),
                    "注释总的字符数     :" + Comment.dirCommentChars(dirPath),
                    "关键字的使用情况如下:"
            };
            for (int i = 0; i < strings.length; i++) {
                bufferedWriter.write(strings[i]);
                bufferedWriter.newLine();
                if (i == 1 || i == 5) {
                    bufferedWriter.newLine();
                }
            }
            ArrayList<String> list = Keyword.writeIntoFile(dirPath);
            for (String s : list) {
                bufferedWriter.write(s);
                bufferedWriter.newLine();
            }
            bufferedWriter.write("------------------------------------------------");
        } catch (IOException e) {
            e.printStackTrace();
        }
        OtherUtils.returnOrNotFile(path);
    }

    /**
     * 存储文件的分析结果
     *
     * @param filePath 文件的路径
     */
    public static void saveFile(String filePath) {
        int id = getId();
        id++;
        setId(id);
        File file = new File(filePath);
        String path = "" + id + "--F_" + file.getName() + "_Result.txt";
        try (final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("src\\data\\" + path))) {
            String[] strings = {
                    "------------------------------------------------",
                    "分析文件          :" + filePath,
                    "源程序中字符总个数 :" + InTotalCharsUtil.javaCharsCount(filePath),
                    "注释总个数        :" + Comment.fileCommentCounts(filePath),
                    "注释总的字符数     :" + Comment.fileCommentChars(filePath),
                    "关键字的使用情况如下:"
            };
            for (int i = 0; i < strings.length; i++) {
                bufferedWriter.write(strings[i]);
                bufferedWriter.newLine();
                if (i == 1 || i == 4) {
                    bufferedWriter.newLine();
                }
            }
            ArrayList<String> list = Keyword.writeIntoFile(filePath);
            for (String s : list) {
                bufferedWriter.write(s);
                bufferedWriter.newLine();
            }
            bufferedWriter.write("------------------------------------------------");
        } catch (IOException e) {
            e.printStackTrace();
        }
        OtherUtils.returnOrNotDir(path);
    }
}


CommentCountsAndCharsUtil

package cn.zg.utils;

import java.util.ArrayList;

/**
 * 注释的个数和字符数的工具类
 *
 * @author zg
 */
public class CommentCountsAndCharsUtil {

    /**
     * 多行注释的结尾
     */
    public static final String END_OF_COMMENT = "*/";
    /**
     * 单行注释
     */
    public static final String SINGLE_LINE_COMMENT = "//";


    /**
     * @param list 存储文件的数组
     * @return 只注释的个数和字符数的数组
     */
    public static long[] operateNote(ArrayList<String> list) {
        String str;
        long countNote = 0;
        long charInNote = 0;
        for (int i = 0; i < list.size(); i++) {

            str = list.get(i);
            int note1 = str.indexOf("/*");
            int note2 = str.indexOf("//");
            int note3 = str.indexOf("*/");

            //  双引号
            String dm = "\"(.*)\"";


            if (note1 != -1 && note3 == -1) {
                //  多行注释
                countNote++;
                String ttt = list.get(i);
                list.set(i, ttt.substring(0, note1));
                //  +1是包括换行符
                charInNote += str.substring(note1).length() + 1;

                str = list.get(++i);
                while (!str.contains(END_OF_COMMENT)) {
                    if (str.contains(SINGLE_LINE_COMMENT)) {
                        countNote++;
                    }
                    list.set(i, "");

                    charInNote += str.length() + 1;
                    if (i < list.size() - 1) {
                        str = list.get(++i);
                    } else {
                        break;
                    }
                }
                list.set(i, "");
                charInNote += str.length();

            } else if (note2 != -1) {
                //  "//"类的单行注释
                countNote++;
                list.set(i, str.substring(0, note2));
                charInNote += str.substring(note2).length() + 1;
            } else if (note1 != -1) {
                //  单行注释
                countNote++;

                String m1 = str.substring(0, note1);
                String m2 = str.substring(note3 + 2);
                String m3 = m1 + m2;
                charInNote += str.substring(note1, note3 + 2).length();
                list.set(i, m3);
            } else {
                //  删除输出语句
                String rp = list.get(i);
                rp = rp.replaceAll(dm, "");
                list.set(i, rp);
            }
        }
        return new long[]{countNote, charInNote};
    }
}


InTotalCharsUtil

package cn.zg.utils;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author zg
 * 统计总的字符数
 */
public class InTotalCharsUtil {

    public static final String JAVA_SUFFIX = ".java";

    /**
     * @param str Java文件名
     * @return java文件的字符数
     */
    public static long javaCharsCount(String str) {
        long count = 0;
        try (FileReader fileReader = new FileReader(new File(str))) {
            while (fileReader.read() != -1) {
                count++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * @param dir 目录名
     * @return 目录中所有源程序的字符总个数
     */
    public static long dirCharsCount(String dir) {
        long count = 0;
        File file = new File(dir);
        File[] files = file.listFiles((dir1, name) ->
                new File(dir1, name).isDirectory() || name.toLowerCase().endsWith(JAVA_SUFFIX));
        if (files == null) {
            return 0;
        }
        for (File f : files) {
            if (f.isFile()) {
                //  getAbsolutePath()使用绝对路径
                count += javaCharsCount(f.getAbsolutePath());
            } else {
                count += dirCharsCount(f.getAbsolutePath());
            }
        }
        return count;
    }
}


JavaFileCountUtil

package cn.zg.utils;

import java.io.File;

/**
 * @author zg
 */
public class JavaFileCountUtil {

    public static final String JAVA_SUFFIX = ".java";

    /**
     * @param str 目录名
     * @return Java源程序文件个数
     */
    public static int javaFileCount(String str) {
        int count = 0;
        File dir = new File(str);
        //  过滤得到文件夹和为.java结尾的文件
        File[] files = dir.listFiles((dir1, name) ->
                new File(dir1, name).isDirectory() || name.toLowerCase().endsWith(JAVA_SUFFIX));
        if (files == null) {
            // 文件数组为空,则无源程序文件
            return 0;
        }
        for (File f : files) {
            if (f.isFile()) {
                count++;
            } else {
                //  getAbsolutePath()使用绝对路径
                count += javaFileCount(f.getAbsolutePath());
            }
        }
        return count;
    }
}


KeySelectUtil

package cn.zg.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

/**
 * @author zg
 */
public class KeySelectUtil {

    public static final String[] KEYWORDS = {
            "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", "short",
            "static", "strictfp", "super", "switch", "synchronized", "this", "throw",
            "throws", "transient", "try", "void", "volatile", "while"
    };

    public static final String END_OF_DOC = "*/";
    public static final String JAVA_SUFFIX = ".java";

    /**
     * 读取文件中的某一行,将该行split为字符串数组,逐个判断是否为关键字.需要首先去除非字母和数字字符的影响
     *
     * @param line     文件名
     * @param keywords 哈希数组
     */
    public static void matchKeywords(String line, Map<String, Integer> keywords) {
        //  使用正则表达式"\\W"匹配任何非单词字符,并替换为空格,然后以空格分割文本
        String[] wordList = line.replaceAll("\\W", " ").split(" ");
        for (String s : wordList) {
            //  遍历字符集
            for (String keyword : KEYWORDS) {
                //循环判断
                if (keyword.equals(s)) {
                    //  如果字符匹配关键字列表中的关键字,键对应的值+1
                    keywords.put(keyword, keywords.get(keyword) + 1);
                }
            }
        }
    }


    /**
     * @param fileName java文件路径名
     * @return 带有关键字和关键字数量map的list集合
     */
    public static Map<String, Integer> fileCountKeyWords(String fileName) {
        Map<String, Integer> keywords = new HashMap<>(128);
        try (BufferedReader input = new BufferedReader(new FileReader(fileName))) {
            for (String word : KEYWORDS) {
                //按KEYWORDS顺序初始化Map
                keywords.put(word, 0);
            }
            String line;
            while ((line = input.readLine()) != null) {
                //  去掉字符串首尾的空格
                line = line.trim();
                if (line.startsWith("//")) {
                    //  单行注释
                    continue;
                } else if (line.contains("/*")) {
                    //  多行,文档与尾行注释
                    if (!line.startsWith("/*")) {
                        //第一行算代码,其余算注释
                        matchKeywords(line, keywords);
                    }
                    while (!line.endsWith(END_OF_DOC)) {
                        //  如果不以"*/"结尾
                        //  去掉字符串首尾的空格
                        //  line = input.readLine().trim()
                        String readLine = input.readLine();
                        if (readLine != null) {
                            line = readLine.trim();
                        }
                    }
                }
                //对代码行进行统计
                matchKeywords(line, keywords);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return keywords;
    }

    /**
     * @param fileName 目录路径名
     * @return 带有关键字和关键字数量map的list集合
     */
    public static Map<String, Integer> dirCountKeyWords(String fileName) {
        File file = new File(fileName);
        File[] files = file.listFiles((dir1, name) ->
                new File(dir1, name).isDirectory() || name.toLowerCase().endsWith(JAVA_SUFFIX));

        Map<String, Integer> keywords = new HashMap<>(128);
        for (String word : KEYWORDS) {
            //按KEYWORDS顺序初始化Map
            keywords.put(word, 0);
        }
        if (files == null) {
            return null;
        }
        for (File f : files) {
            if (f.isFile()) {
                // getAbsolutePath()使用绝对路径
                Map<String, Integer> map = fileCountKeyWords(f.getAbsolutePath());
                for (String keyword : map.keySet()) {
                    keywords.put(keyword, keywords.get(keyword) + map.get(keyword));
                }
            } else {
                Map<String, Integer> map = dirCountKeyWords(f.getAbsolutePath());
                if (map != null) {
                    for (String keyword : map.keySet()) {
                        keywords.put(keyword, keywords.get(keyword) + map.get(keyword));
                    }
                }
            }
        }
        return keywords;
    }

    /**
     * @param keywords map
     * @return map转化为List数组并排序
     */
    public static List<Map.Entry<String, Integer>> mapIntoListAndSort(Map<String, Integer> keywords) {
        //  将map.entrySet()转换为list
        List<Map.Entry<String, Integer>> list = new ArrayList<>(keywords.entrySet());
        //  优先按值降序排序,值相同按键的字典序排序
        list.sort((o1, o2) -> {
            if (o2.getValue().equals(o1.getValue())) {
                return String.CASE_INSENSITIVE_ORDER.compare(o1.getKey(), o2.getKey());
            }
            return o2.getValue() - o1.getValue();
        });
        return list;
    }
}


OtherUtils

package cn.zg.utils;

import cn.zg.frame.Start;

import java.util.Scanner;

/**
 * @author zg
 */
public class OtherUtils {

    public static void returnOrNotFile(String path){
        System.out.println("文件分析结束, 分析结果存放在文件[data\\"+path+"]! ");
        System.out.println();
        System.out.println();
        System.out.print("返回上一层请输入1,退出请输入0:");
        boolean flag=true;

        while(flag){
            int input=new Scanner(System.in).nextInt();
            if(input==1){
                Start.mainFrame();
                flag=false;
            }else if(input==0){
                flag=false;
                System.exit(0);
            }else{
                System.out.print("输入有误!请重新输入!返回上一层请输入1,退出请输入0:");
            }
        }
    }

    /**
     * 返回或者退出
     * @param path 数据存储的文件名
     */
    public static void returnOrNotDir(String path){
        System.out.println("目录分析结束, 分析结果存放在文件[data\\"+path+"]! ");
        System.out.println();
        System.out.println();
        System.out.print("返回上一层请输入1,退出请输入0:");
        boolean flag=true;

        while(flag){
            int input=new Scanner(System.in).nextInt();
            if(input==1){
                System.out.println();
                System.out.println();
                Start.mainFrame();
                flag=false;
            }else if(input==0){
                flag=false;
                System.exit(0);
            }else{
                System.out.print("输入有误!请重新输入!返回上一层请输入1,退出请输入0:");
            }
        }
    }
}


TextIntoListUtil

package cn.zg.utils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author zg
 */
public class TextIntoListUtil {

    /**
     * @param filePath 文件路径
     * @return 把文件存进List数组中
     */
    public static ArrayList<String> fileList(String filePath) {

        ArrayList<String> list = new ArrayList<>();
        try (final BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                list.add(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
}







emm,只是格式要求有点烦人。



源码自取:

https://gitee.com/keepOrdinary/Comprehensive

  • 16
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值