映射与重复键和文件写入

时间:2018-04-11 15:05:12

标签: java file

我正在尝试输出类似这样的输出

project     class
kata        FizzBuzz
kata        FizzBuzzTest
kata        Anagrams    
kata        AnagramsTest
emacs4ij    BufferTest
emacs4ij    TestSetup
emacs4ij    TestFrameManagerImp

我使用Files.walkFileTree(Paths.get(path), this);浏览了目录,然后创建了Map并将值放入其中。地图不允许使用多个密钥,因此我打印时只会将kata AnagramsTestemacs4ij TestFrameManagerTmp作为地图中的值。在控制台上打印结果表明我已经掌握了所有内容。

以下是我尝试过的简短代码

public class MyFileIterator extends SimpleFileVisitor<Path>{

Map<String, String> contentMap = new HashMap<String, String>();
public MyFileIterator(String path) throws Exception{
    Files.walkFileTree(Paths.get(path), this);
}

 @Override
public FileVisitResult visitFile(Path file,
        BasicFileAttributes attributes) throws IOException{
    Objects.requireNonNull(file);
    if (file.getFileName().toString().toLowerCase().endsWith(".java")) {
        //getName(5) will give the Project Name
        System.out.println("project name is: "+file.getName(5));
        System.out.println("Located file: " + file.getFileName().toString());
        contentMap.put(file.getName(5).toString(),file.getFileName().toString());            
    }
    writeUsingFileWriter(contentMap);
    return FileVisitResult.CONTINUE;
}

我还尝试使用Map<String, List<String>)Map<List<String>, String>,但没有成功

为了编写文件并创建所需的输出,我做了类似的事情

private static void writeUsingFileWriter(Map<String,String> tempMap) {

     try(Writer writer = Files.newBufferedWriter(Paths.get(//maypath here))) {
         tempMap.forEach((key, value) -> {
            try { System.out.println(key + " " + value); 
                writer.write(key + " " + value + System.lineSeparator()); }
            catch (IOException ex) { throw new UncheckedIOException(ex); }
        });
    } catch(UncheckedIOException | IOException ex) { ex.getCause(); }

在主要方法中我做了类似的事情

String path = Paths.get(".").toAbsolutePath().normalize().toString();
    try {
        MyFileIterator temp = new MyFileIterator(path);         
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

因此,如果项目位于以下路径,请说:​​C:\ code \ kata \ FizzBu​​zz.java

我正在尝试获取 Kata FizzBu​​zz - &gt;(可能需要使用标记化或拆分或正则表达式来切割此路径并获取期望的结果......甚至需要剪切.java)并将其放在地图中并以上面给出的格式写在文件上。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

这是您的更新代码。如上所述,您的问题是您每次访问新文件时都打印了所访问的所有文件......

public class MyFileVisitor extends SimpleFileVisitor<Path> {

    private Map<String, List<String>> contentMap = new HashMap<>();

    public static void main(String[] args) throws Exception {
        MyFileVisitor myVisitor = new MyFileVisitor();
        myVisitor.collectAllJavaFilesInFileTree(Paths.get("C:\\root\\dir"));
        myVisitor.writeUsingFileWriter(Paths.get("C:\\file\\to\\write.txt"));
    }

    public void collectAllJavaFilesInFileTree(Path root) throws IOException {
        Files.walkFileTree(root, this);
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
        Objects.requireNonNull(file);
        final String fileName = file.getFileName().toString();
        if (fileName.toLowerCase().endsWith(".java")) {
            // project name will be null if path isn't at least 5 deep...
            String projectName = null;
            if (file.getNameCount() >= 5) {
                projectName = file.getName(5).toString();
            }

            String key = projectName;
            List<String> list = contentMap.get(key);
            if (list == null) {
                list = new ArrayList<String>();
                contentMap.put(key, list);
            }
            list.add(fileName);
        }
        return FileVisitResult.CONTINUE;
    }


    public void writeUsingFileWriter(Path fileToWrite) {
        try (Writer writer = Files.newBufferedWriter(fileToWrite)) {
            contentMap.forEach((key, valueList) -> {
                try {
                    for (String value : valueList) {
                        writer.write(key + " " + value + System.lineSeparator());
                    }
                } catch (IOException ex) {
                    throw new UncheckedIOException(ex);
                }
            });
        } catch (UncheckedIOException | IOException ex) {
            ex.printStackTrace();
        }
    }
}

答案 1 :(得分:0)

使用Map<String, List<String>>

Map<String, List<String>> contentMap = new HashMap<>();
// ...

public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException{
    Objects.requireNonNull(file);
    if (file.getFileName().toString().toLowerCase().endsWith(".java")) {
        // getName(5) will give the Project Name
        System.out.println("project name is: " + file.getName(5));
        System.out.println("Located file: " + file.getFileName().toString());

        // vvv NEW STUFF vvv
        String key = file.getName(5).toString();
        List<String> list = contentMap.get(key);
        if(list == null){
            // if the list didn't exist then create it
            list = new ArrayList<String>();
            contentMap.put(key, list);
        }
        list.add(file.getFileName().toString());
    }
    writeUsingFileWriter(contentMap);
    return FileVisitResult.CONTINUE;
}
private static void writeUsingFileWriter(Map<String, List<String>> tempMap) {
    try(Writer writer = Files.newBufferedWriter(Paths.get("myPath"))){
        tempMap.forEach((key, value) -> {
            try {
                for(String s : value){
                    System.out.println(key + " " + s); 
                    writer.write(key + " " + s + System.lineSeparator());
                }
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        });
    } catch(UncheckedIOException | IOException ex) {
        ex.printStackTrace();
    }
}

如果需要,您还可以使用便捷方法从地图中的列表中删除内容和/或删除列表中的内容。

答案 2 :(得分:0)

详细阐述@NielsNet的评论,也许你可以试试List Entry。类似的东西:

private final List<Map.Entry<String, String>> content = new LinkedList<>();

...

    @Override
    public FileVisitResult visitFile(Path file,
                                     BasicFileAttributes attributes) throws IOException {
        Objects.requireNonNull(file);
        if (file.getFileName().toString().toLowerCase().endsWith(".java")) {
            //getName(5) will give the Project Name
            System.out.println("project name is: " + file.getName(5));
            System.out.println("Located file: " + file.getFileName().toString());
            content.add(new SimpleEntry<>(file.getName(5).toString(), file.getFileName().toString()));
        }
...