【问题标题】:How to use an ArrayList inside a method that calls itself如何在调用自身的方法中使用 ArrayList
【发布时间】:2015-02-12 06:55:22
【问题描述】:

我有这段代码是在一个名为FileUtils 的类中实现的,它听起来像。 它所做的只是遍历一个文件并将该文件夹下的每个文件夹放在ArrayList 中,因此它就像在任何将返回内容的文件上调用.listFiles() 方法一样。

private static ArrayList<File> classFileList = new ArrayList<File>();

public static ArrayList<File> listFiles(File dir) {
    if (!dir.isDirectory() || !dir.exists()) 
        return null;
    for (File file : dir.listFiles()) {
        classFileList.add(file);
        listFiles(file);
    }
    return classFileList;
}

上面的代码工作正常,但它需要一个类变量ArrayList 才能工作。

如果我在方法内创建ArrayList,那么每次调用它时都会重置它,并且只返回最后一个文件。但是通过我现在的设置,如果我多次调用该方法,则列表包含每个文件的重复项。

使用方法变量或在调用后重置类变量。

【问题讨论】:

    标签: java recursion arraylist class-variables


    【解决方案1】:

    您可以在函数内部创建一个局部变量,并在递归调用时为其创建addAll

    public static List<File> listFiles(File dir) {
        List<File> result = new ArrayList<>();
        if (!dir.isDirectory() || !dir.exists()) 
            return result; // Alternatively: return Collections.emptyList();
    
        for (File file : dir.listFiles()) {
            result.add(file);
            result.addAll(listFiles(file));
        }
        return result;
    }
    

    【讨论】:

    • 这样做会不会占用大量处理器,因为您需要运行该方法来查找所有文件,然后为每个文件再次调用它?
    • ... 与 OP 一样 - 这不再是处理器密集型的。
    • @Panther 这根本不是真的。仔细看看——for循环的最后一行将结果累加
    • @Panther 当然,我确实对此进行了测试。 了吗?每次调用都会重新定义局部变量 - 它们不会“重置”,它们只是不同的变量。请在发出此类语句之前尝试实际运行它。
    • 你能编辑问题吗,比如添加一些空间。我喜欢删除我的反对票,实际上也投了票。它为我锁定了
    【解决方案2】:

    为您的方法添加参数列表并从其他方法调用它并在该方法中初始化新列表并将其传递给现有方法。公开新方法而不是现有方法:-

      public static ArrayList<File> listFilesWrapper(File dir){
         listFiles (dir , new ArrayList<File>());
    
       }
    
     public static ArrayList<File> listFiles(File dir,ArrayList<File> classFileList) {
    
    
    if (!dir.isDirectory() || !dir.exists()) 
        return null;
    for (File file : dir.listFiles()) {
        classFileList.add(file);
        listFiles(file , classFileList);
    }
    return classFileList;
    }
    

    【讨论】:

    • 是的,这是我在发布后立即想到的,我只是这样做了,效果很好,所以我认为这是一个很好的答案,但是你需要传递 classFileList 并在调用它时作为参数for 循环。只要您进行编辑,我就会接受这个作为答案
    • @Totalllyrandomguy 完成,感谢您指出。实际上我在这台计算机上没有java,所以在记事本中编写了代码。并从您的问题中复制粘贴该部分。 :-)
    • 您还需要传递文件 - listFiles() 有 2 个参数!此外,如果您将 classFileList 作为参数传递,则该方法可能应该具有 void 返回类型。
    • 不,它不应该具有 void 返回类型,因为此方法在需要它的单独类形式中发生。所以它需要在内部创建一个arrayList,然后需要将它返回到它被调用的地方。
    【解决方案3】:
    public static void listFiles(File dir, List<File> files) {
        if (!dir.isDirectory()) 
            return;
        for (File file : dir.listFiles()) {
            files.add(file);
            listFiles(file, files);
        }
    }
    

    然后要获取目录中所有文件的列表,请使用此代码;

    List<File> files = new ArrayList<File>();
    listFiles(dir, files); // Now the result is contained in files.
    

    【讨论】:

      猜你喜欢
      • 2017-10-22
      • 1970-01-01
      • 2014-04-22
      • 2012-07-10
      • 2018-03-27
      • 2017-04-18
      • 2016-01-30
      • 2018-01-12
      • 1970-01-01
      相关资源
      最近更新 更多