Java 打印出文件结构中的最后一个父文件夹,但获取重复项…可能需要重写equals和hashCode吗?

Java 打印出文件结构中的最后一个父文件夹,但获取重复项…可能需要重写equals和hashCode吗?,java,hashset,Java,Hashset,我正在开发一个程序,它将遍历系统的文件结构,递归地确定并打印出结构中最后的父文件夹。例如,如果我有一个这样设置的系统: C:\aaa\bbb\ccc\file1.txt C:\aaa\bbb\ccc\file2.txt C:\aaa\bbb\ddd\fileA.txt 程序将打印“ccc”和“ddd” 但是,许多最终父文件夹包含多个文件。事实上,几乎所有人都这样做。我不想打印出重复的文件夹名称,所以我尝试使用哈希集,因为我知道哈希集不允许重复。但我的作品集确实在添加重复的作品 我做了一些阅读,

我正在开发一个程序,它将遍历系统的文件结构,递归地确定并打印出结构中最后的父文件夹。例如,如果我有一个这样设置的系统:

C:\aaa\bbb\ccc\file1.txt
C:\aaa\bbb\ccc\file2.txt
C:\aaa\bbb\ddd\fileA.txt
程序将打印“ccc”和“ddd”

但是,许多最终父文件夹包含多个文件。事实上,几乎所有人都这样做。我不想打印出重复的文件夹名称,所以我尝试使用哈希集,因为我知道哈希集不允许重复。但我的作品集确实在添加重复的作品

我做了一些阅读,我想这可能是我需要重写equals()和hashCode()方法的情况。但我有两个与此相关的问题:

1) 既然我正在向HashSet添加字符串对象,而不是新的/唯一类类型的对象,为什么我需要重写这些方法?我理解为什么Java可能不知道如何比较唯一类类型的对象,但它知道如何比较字符串,所以

2) 如果我确实需要重写equals()和hashCode(),那么我的代码当前不包含任何可用于进行此类比较的非静态字段,并且我不确定从当前代码中提取非静态字段的最佳方法是什么

这是我到目前为止的代码。它将运行并打印出大量重复值:

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

public class FileInformationMain {

    public static void main (String [] args) {

        System.out.println("File System Roots returned by File.listRoots(): ");
        System.out.println();
        File [] f = File.listRoots();

        for (int i = 0; i < f.length; i++) {
            System.out.println("Drive: " + f[i]);
            System.out.println();
            System.out.println("List of lowest level parent directories: ");
            File [] files = f[i].listFiles();
            if (files != null) {
                for (File file : files) {
                    getFileNames(file);
                }
            }
        }
    }

    public static void getFileNames(File aFile) {
        set <String> parents = new HashSet<String>();
        if (!aFile.isDirectory()) {
            set.add(aFile.getParent());
        }
        else {
            File [] children = aFile.listFiles();
            if (children != null) {
                for (int x = 0; x < children.length; x++) {
                    getFileNames(children[x]);
                }
        } 
        for (String string : parents) System.out.println(string);
    }
}
import java.io.*;
导入java.util.ArrayList;
导入java.util.HashSet;
导入java.util.Set;
公共类FileInformationMain{
公共静态void main(字符串[]args){
System.out.println(“File.listRoots()返回的文件系统根:”;
System.out.println();
File[]f=File.listRoots();
对于(int i=0;i
由于
集合
对象没有添加重复的
字符串
对象,因此该对象工作正常。问题在于调用递归方法的方式。每次调用该方法时,您都会创建一个新的
集合
对象,并在方法末尾打印其内容。
集合
instance应以递归方式传递给该方法,以便用唯一的父路径名填充。然后在递归调用结束时,您将打印出路径名列表:

import java.io.File;
import java.util.HashSet;
import java.util.Set;

public class FileInformationMain {

   public static void main(String[] args) {

       System.out.println("File System Roots returned by File.listRoots(): ");
       System.out.println();
       File[] f = File.listRoots();

       Set<String> parents = new HashSet<String>();
       for (int i = 0; i < f.length; i++) {
           System.out.println("Drive: " + f[i]);
           System.out.println();
           System.out.println("List of lowest level parent directories: ");
           File[] files = f[i].listFiles();
           if (files != null) {
               for (File file : files) {
                   getFileNames(file, parents);
               }
           }
       }
       for (String string : parents)
           System.out.println(string);
   }

   public static void getFileNames(File aFile, Set<String> parents) {
       if (!aFile.isDirectory()) {
           parents.add(aFile.getParent());
       } else {
           File[] children = aFile.listFiles();
           if (children != null) {
               for (int x = 0; x < children.length; x++) {
                   getFileNames(children[x], parents);
               }
           }
       }
   }
}
导入java.io.File;
导入java.util.HashSet;
导入java.util.Set;
公共类FileInformationMain{
公共静态void main(字符串[]args){
System.out.println(“File.listRoots()返回的文件系统根:”;
System.out.println();
File[]f=File.listRoots();
Set parents=new HashSet();
对于(int i=0;i
在何处打印哈希集的内容?您正在递归地使用该方法,但从不返回任何内容,并且打印内容的代码不是任何方法的一部分。请提供您正在使用的正确代码。“使用集”是什么意思?集合是一个接口,你不需要一个具体的类型来实例化一些东西吗?Stephan,我会打印内容,这是代码的最后一行。每个递归调用实例化一个新集合(它甚至不会在你的代码中编译).编辑:对不起,我刚刚意识到我的打印声明放错了地方;它被移动了。这是真的!我真蠢。谢谢你马努蒂(还有guido,他在上面的评论中提到了这一点)!