与Map相关的java程序出错

时间:2012-06-30 16:38:43

标签: java collections map

我开发了一个应用程序,用户在其中选择特定文件夹,它会计算该文件夹中的所有java文件以及这些文件中单独的代码行,并在控制台中显示但在java项目中有很多软件包并且正确现在我必须导航到一个特定的包,我想以这样的方式修改应用程序,当用户选择特定项目时,他将进一步导航到只有src文件夹并从src文件夹中包含所有包含java文件的代码行将被计算在内。

public class abc {

    /**
     * @param args
     * @throws FileNotFoundException
     */
    private static int totalLineCount = 0;
    private static int totalFileScannedCount = 0;

    public static void main(String[] args) throws FileNotFoundException {

        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
        chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            Map<String, Integer> result = new HashMap<String, Integer>();
            File directory = new File(chooser.getSelectedFile().getAbsolutePath());

            List<File> files = getFileListing(directory);

            //print out all file names, in the the order of File.compareTo()
            for (File file : files) {
                System.out.println("Directory: "+file);
                result = getFileLineCount(file);
                totalFileScannedCount +=  result.size();
            }


            System.out.println("*****************************************");
            System.out.println("FILE NAME FOLLOWED BY LOC");
            System.out.println("*****************************************");

            for (Map.Entry<String, Integer> entry : result.entrySet()) {
                System.out.println(entry.getKey() + " ==> " + entry.getValue());
            }
            System.out.println("*****************************************");
            System.out.println("SUM OF FILES SCANNED ==>" + "\t" + totalFileScannedCount);
            System.out.println("SUM OF ALL THE LINES ==>" + "\t" + totalLineCount);

        }

    }

    public static Map<String, Integer> getFileLineCount(File directory) throws FileNotFoundException {
        Map<String, Integer> result = new HashMap<String, Integer>();

        File[] files = directory.listFiles(new FilenameFilter() {

            @Override
            public boolean accept(File directory, String name) {
                if (name.endsWith(".java")) {
                    return true;
                } else {
                    return false;
                }
            }
        });
        for (File file : files) {
            if (file.isFile()) {
                Scanner scanner = new Scanner(new FileReader(file));
                int lineCount = 0;
                try {
                    for (lineCount = 0; scanner.nextLine() != null; lineCount++);
                } catch (NoSuchElementException e) {
                    result.put(file.getName(), lineCount);
                    totalLineCount += lineCount;
                }
            }
        }

        return result;
    }

    /**
     * Recursively walk a directory tree and return a List of all
     * Files found; the List is sorted using File.compareTo().
     *
     * @param aStartingDir is a valid directory, which can be read.
     */
    static public List<File> getFileListing(
            File aStartingDir) throws FileNotFoundException {
        validateDirectory(aStartingDir);
        List<File> result = getFileListingNoSort(aStartingDir);
        Collections.sort(result);
        return result;
    }

    // PRIVATE //
    static private List<File> getFileListingNoSort(
            File aStartingDir) throws FileNotFoundException {
        List<File> result = new ArrayList<File>();
        File[] filesAndDirs = aStartingDir.listFiles();
        List<File> filesDirs = Arrays.asList(filesAndDirs);
        for (File file : filesDirs) {
            if(file.isDirectory()) {
                result.add(file); 
            }
            if (!file.isFile()) {
                //must be a directory
                //recursive call!
                List<File> deeperList = getFileListingNoSort(file);
                result.addAll(deeperList);
            }
        }
        return result;
    }

    /**
     * Directory is valid if it exists, does not represent a file, and can be read.
     */
    static private void validateDirectory(
            File aDirectory) throws FileNotFoundException {
        if (aDirectory == null) {
            throw new IllegalArgumentException("Directory should not be null.");
        }
        if (!aDirectory.exists()) {
            throw new FileNotFoundException("Directory does not exist: " + aDirectory);
        }
        if (!aDirectory.isDirectory()) {
            throw new IllegalArgumentException("Is not a directory: " + aDirectory);
        }
        if (!aDirectory.canRead()) {
            throw new IllegalArgumentException("Directory cannot be read: " + aDirectory);
        }
    }
}

现在问题是这个方法的问题是,如果在名为TESTRESULT的java项目中有3个包,每个包每个包含2个文件,那么在控制台上的结果中它显示文件名,后面只有最新包的loc让我们在一个名为abc,def和tyu

的java projest 3包中说
com.abc package having files --->abc.java
com.def package having files --->abc.java
com.tyu package having files --->FileBrowse.java , FileCountLine.java

the outcome shown in console is... 


    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\.settings
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\bin
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\src
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\src\com
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\src\com\abc
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\src\com\def
    Directory: C:\Users\vaio\Desktop\Demo\TESTRESULT\src\tyu
    *****************************************
    FILE NAME FOLLOWED BY LOC
    *****************************************
    FileBrowse.java ==> 95
    FileCountLine.java ==> 53
    *****************************************
    SUM OF FILES SCANNED ==> 4
    SUM OF ALL THE LINES ==> 296

这并不完美。请告知如何显示所有文件的LOC后面的文件

我的想法在读取文件和行数的方法中,为每个目录创建一个新的Map,并将其重新分配给相同的结果。由于在重新分配Map之前不显示数据,因此无法再访问上一个Map,当您到达显示时,只有最后一个目录的Map。相反,您应该维护一个Map并将每个目录中的新值插入到同一个Map中。

public static void main(String[] args) throws FileNotFoundException {  
            //...  
            for (File file : files) {  
                System.out.println("Directory: "+file);  
                result = getFileLineCount(file);

在那里,您从getFileLineCount()返回一张地图,然后将其分配给结果。这将丢弃先前创建的结果Map,并且您将丢失已存在的所有内容。您有几个选择:

  1. 将结果地图传递到getFileLineCount()方法,以便您可以将结果添加到一个地图,而不是为getFileLineCount()方法中的每个文件夹创建新地图
  2. getLineCount()获取结果并将其复制到结果Map中,而不是替换结果Map
  3. 创建另一个集合,例如:Map<String, Map<String, Integer>>(将getFileLineCount()方法返回的结果映射到这些结果所属目录的名称),或List<Map<String, Integer>> (这是getFileLineCount()返回的结果的简单列表,没有任何映射到父目录。)
  4. 请提前告知如何重构我的代码

1 个答案:

答案 0 :(得分:3)

你可以这样做:

result.put(file, lineCount);

而不是

result.put(file.getName(), lineCount);

当您打印结果时,您可以打印漂亮的文件名。像这样:

for (Map.Entry<File, Integer> entry : result.entrySet()) {
    System.out.println(entry.getKey().getName() + " ==> " + entry.getValue());
}

当然,地图应该声明为:Map.Entry<File, Integer>


当然这可以改进很多,但是只需要做很少的改动就可以了(实际上是按照你的期望做的,如果你不想要整个路径,请改变打印名称):

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Scanner;

import javax.swing.JFileChooser;

public class abc {

    /**
     * @param args
     * @throws FileNotFoundException
     */
    private static int totalLineCount = 0;
    private static int totalFileScannedCount = 0;

    public static void main(final String[] args) throws FileNotFoundException {

        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new java.io.File("C:" + File.separator));
        chooser.setDialogTitle("FILES ALONG WITH LINE NUMBERS");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            Map<File, Integer> result = new HashMap<File, Integer>();
            File directory = new File(chooser.getSelectedFile().getAbsolutePath());

            List<File> files = getFileListing(directory);

            // print out all file names, in the the order of File.compareTo()
            for (File file : files) {
                System.out.println("Directory: " + file);
                getFileLineCount(result, file);
            }

            System.out.println("*****************************************");
            System.out.println("FILE NAME FOLLOWED BY LOC");
            System.out.println("*****************************************");

            for (Map.Entry<File, Integer> entry : result.entrySet()) {
                System.out.println(entry.getKey().getAbsolutePath() + " ==> " + entry.getValue());
            }
            System.out.println("*****************************************");
            System.out.println("SUM OF FILES SCANNED ==>" + "\t" + totalFileScannedCount);
            System.out.println("SUM OF ALL THE LINES ==>" + "\t" + totalLineCount);
        }

    }

    public static void getFileLineCount(final Map<File, Integer> result, final File directory)
            throws FileNotFoundException {
        File[] files = directory.listFiles(new FilenameFilter() {

            public boolean accept(final File directory, final String name) {
                if (name.endsWith(".java")) {
                    return true;
                } else {
                    return false;
                }
            }
        });
        for (File file : files) {
            if (file.isFile()) {
                totalFileScannedCount++;
                Scanner scanner = new Scanner(new FileReader(file));
                int lineCount = 0;
                try {
                    for (lineCount = 0; scanner.nextLine() != null; lineCount++) {
                        ;
                    }
                } catch (NoSuchElementException e) {
                    result.put(file, lineCount);
                    totalLineCount += lineCount;
                }
            }
        }

    }

    /**
     * Recursively walk a directory tree and return a List of all Files found;
     * the List is sorted using File.compareTo().
     * 
     * @param aStartingDir
     *            is a valid directory, which can be read.
     */
    static public List<File> getFileListing(final File aStartingDir) throws FileNotFoundException {
        validateDirectory(aStartingDir);
        List<File> result = getFileListingNoSort(aStartingDir);
        Collections.sort(result);
        return result;
    }

    // PRIVATE //
    static private List<File> getFileListingNoSort(final File aStartingDir) throws FileNotFoundException {
        List<File> result = new ArrayList<File>();
        File[] filesAndDirs = aStartingDir.listFiles();
        List<File> filesDirs = Arrays.asList(filesAndDirs);
        for (File file : filesDirs) {
            if (file.isDirectory()) {
                result.add(file);
            }
            if (!file.isFile()) {
                // must be a directory
                // recursive call!
                List<File> deeperList = getFileListingNoSort(file);
                result.addAll(deeperList);
            }
        }
        return result;
    }

    /**
     * Directory is valid if it exists, does not represent a file, and can be
     * read.
     */
    static private void validateDirectory(final File aDirectory) throws FileNotFoundException {
        if (aDirectory == null) {
            throw new IllegalArgumentException("Directory should not be null.");
        }
        if (!aDirectory.exists()) {
            throw new FileNotFoundException("Directory does not exist: " + aDirectory);
        }
        if (!aDirectory.isDirectory()) {
            throw new IllegalArgumentException("Is not a directory: " + aDirectory);
        }
        if (!aDirectory.canRead()) {
            throw new IllegalArgumentException("Directory cannot be read: " + aDirectory);
        }
    }
}