繁体   English   中英

在可从主Java访问的静态方法中创建数组

[英]Creating an array inside a static method accessible from main Java

这是我尝试在静态方法中创建数组的糟糕尝试。 该程序的作用是列出具有一定扩展名的文档。 我希望能够将它们存储在数组中并从main访问该数组。 可能吗? 到目前为止,这是我的代码:

package recogniseKeywords;

import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;

import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

public class KeywordsRecognition {

    public static void listFilesForFolder(final File folder) {

        String[] files = {};
        int fileSize = 0;

        String[] extensions = {".doc", ".docm", ".xls"};

        for (final File fileEntry : folder.listFiles()) {
            if (fileEntry.isDirectory()) {
                listFilesForFolder(fileEntry);
            } else {

                for(int i=0; i<extensions.length; i++) {
                    //Check if contains one of the extensions and isn't a temporary file(~$)
                    if (fileEntry.getName().contains(extensions[i]) && !fileEntry.getName().startsWith("~$")) {
                        System.out.println(fileEntry.getName());
                        files[fileSize] = fileEntry.getName();
                        fileSize++;
                    }
                }
            }
        }

    }

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

        String[] keywords = {"Performance Enhancement", "Functional Specification", "Technical Specification", "Faults", "Arval", "Vehicle", "Fines", "Insurance"};


            final File folder = new File("C:/work");
            listFilesForFolder(folder);

            System.out.println(Arrays.toString(files));

        }
    }
}

我知道这是一个静态方法,并且不将int以及数组视为非静态方法,但是,我不知道如何进一步进行。

我能给你的最好的指示是离开静态领域的魔掌,进入实例化领域,即面向对象的机会之域!

在您的主要方法中执行以下操作:

public static void main(String[] args) throws Exception {    
    KeywordsRecognition app = new KeywordsRecognition();
    app.start();
}

然后实施start方法并在那里开始工作。 这样做将为您的代码设计提供更多选择,使您可以编写更具可读性和可测试性的代码,从而减少错误和维护问题。

要访问listFilesForFolder的结果,可以将其返回,将其分配给字段或将其添加到集合中。 既然您要递归,我会说:将其添加到集合中。

基本原理:每个递归都添加到同一集合中。 您不希望中间结果对递归以外的其他代码可见,因此请避免使用字段并使用方法参数。 同样,以这种方式通过递归传递数据是很常见的,因此其他开发人员将理解它。

private static final String ROOT_FOLDER_DEFAULT = "C:/work";
private static final String[] EXTENSIONS = {".doc", ".docm", ".xls"};
// TODO: the keywords are not used anywhere yet
private static final String[] KEYWORDS = {"Performance Enhancement", "Functional Specification", "Technical Specification", "Faults", "Arval", "Vehicle", "Fines", "Insurance"};

public void start(String rootFolder) {       
    List<String> files = new ArrayList<>();
    readFilesRecursively(new File(rootFolder), files);
    // trick to print list contents by converting to array
    System.out.println(Arrays.toString(files.toArray()));
}        

// recursion is not that common so when you use it, 
// it's a good idea to clearly indicate this in the method name
public void readFilesRecursively(File folder, List<String> files) {
    for (File file : folder.listFiles()) {
        if (file.isDirectory()) {
            readFilesRecursively(file, files);
        } else {
            for(String extension : EXTENSIONS) {
                String fileName = file.getName();
                if (fileName.contains(extension ) && !isTemporaryFile(fileName)) {
                    files.add(fileName);
                }
            }
        }
    }
}

// if you find yourself adding a comment in the middle of your code
// that usually means you need to extract a method for that bit
private boolean isTemporaryFile(String fileName) {
    return fileName.startsWith("~$");
}

public static void main(String[] args) throws Exception {    
    KeywordsRecognition app = new KeywordsRecognition();
    app.start(getRootFolder(args));
}

private static String getRootFolder(String[] args) {
    if(args != null && args.length > 0) {
        return args[0];
    }
     else {
        return ROOT_FOLDER_DEFAULT:
    }
}

旁注:您不能增加数组的大小; 创建后,其大小是固定的。 因此,要么将数组初始化为正确的长度,要么使用java.util.List代替(可以选择在完全填充List之后将其转换为数组):

List<String> values = new ArrayList<>();
values.add("1");
values.add("foo");
values.add("elderberries");
String[] valuesAsArray = values.toArray();

或者,或者:

String[] valuesAsArray = new String[3];
values[0] = "1";
values[1] = "foo";
values[2] = "elderberries";

mainlistFilesForFolder中看不到files变量的原因是files是一个局部变量 它的范围是listFilesForFolder方法本身。 (如果您将mainlistFilesForFolder声明为实例方法,则情况仍然如此。)

有许多可能的解决方案。 最简单的是:

  1. 返回值files作为listFilesForFolder的结果,并在main使用返回的值。

  2. files声明为static变量,而不是局部变量。

  3. files声明为实例变量,然后将代码更改为更面向对象。 参见Adrian的答案。

在这些方法中,1和3更好。 方法2将在类似这样的简单示例中工作,但是(由于各种原因)在大型应用程序中会出现问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM