简体   繁体   English

如何创建返回字符串或 ArrayList 的 java 泛型方法<string></string>

[英]how to create java generic method which returns String or ArrayList<String>

As a part of self-improvement, I'm practising generics in java, and I have a case - It's just a learning case - not a real-world scenario... I'm trying to write a generic method which takes a string as an argument and based on return type it should return either String or List.作为自我提升的一部分,我正在 java 中练习 generics,我有一个案例 - 这只是一个学习案例 - 不是真实世界的场景......我正在尝试编写一个采用字符串的通用方法作为参数并基于返回类型,它应该返回字符串或列表。

In the normal (easy logic) situation I've done like that:在正常(简单的逻辑)情况下,我已经这样做了:

public class ConfigFile{

    String fileName;

    public ConfigFile(String filename) {
        this.fileName = filename;
    }

    public String getFilename() {
        return fileName;
    }

    public String readFileAndReturnString() {
        String content = "";
        try {
            BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)));
            String line;

            while ((line = br.readLine()) != null) {
                content = content.concat(line + "\n");
            }
        } catch (IOException e) {
            System.out.println("== IO exception");
            e.printStackTrace();
        }
        return content;

    }

    public ArrayList<String> readFileAndReturnStringArr(String filename) {
        List<String> content = new ArrayList<>();
        try {
            BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)));
            String line;

            while ((line = br.readLine()) != null) {
                content.add(line);
            }
        } catch (IOException e) {
            System.out.println("== IO exception");
            e.printStackTrace();
        }
        return content;
    }
}

I can test them easily:我可以轻松地测试它们:

...
@Test
public void printStringTest() {
    String someStrFile = configFile.readFileAndReturnString();  
    System.out.println(String.format("==== str: %s", someStrFile));
}
    
@Test
public void printArrayTest() {
    ArrayList<String> someArrFile = configFile.readFileAndReturnStringArr();
    for (String line : someArrFile) {
        System.out.println(String.format("arr: %s", line));
    }
}
...

Now i would like to make a generic method which would merge logic from both of methods and i'can't figure out how can I achieve this (if it's even possible)现在我想制作一个通用方法,它将两种方法的逻辑合并,我不知道如何实现这一点(如果可能的话)

    public <T> T readTheFile() {
   //     ...implementation
    }

to use it like this:像这样使用它:

ConfigFile someConfFile = new ConfigFile("C:\\temp\\someFile.txt");
String strConfFile = someConfFile.readTheFile(); //to return here String
ArrayList<String> arrConfFile = someConfFile.readTheFile(); //to return here ArrayList<String>

I've tried few things but I failed.我尝试了几件事,但我失败了。 Can you please help me figure out that?你能帮我弄清楚吗? Or maybe there is some other solution for such case or maybe it totally doesn't make sense或者对于这种情况可能还有其他解决方案,或者它完全没有意义

Thanks in advance提前致谢

You don't really have to use generics, but simply extract the common code you have into another method (adapted the code slighty to use modern idioms):您实际上不必使用 generics,而只需将您拥有的通用代码提取到另一种方法中(稍微修改代码以使用现代成语):

public void readFileInto(Consumer<? super String> accumulator) {
    try(BufferedReader br = new BufferedReader(new FileReader(new File(this.fileName)))) {
        
        String line;
        while ((line = br.readLine()) != null) {
            accumulator.accept(line);
        }
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

Which the two other methods then can delegate to:然后其他两种方法可以委托给:

public String readFileAndReturnString() {
    StringBuilder sb = new StringBuilder();
    readFileInto(sb::append);
    return sb.toString();
}

public ArrayList<String> readFileAndReturnStringArr(String filename) {
    ArrayList<String> list = new ArrayList<>();
    readFileInto(list::add);
    return list;
}

If you are not wise in the arts of lambdas and method references which look like this:如果您在 lambdas 和方法引用方面不明智,看起来像这样:

  • foo -> bar(foo)
  • this::bar
  • Baz::bar

Then I suggest reading the following article: Lambda expressions那么我建议阅读以下文章: Lambda 表达式

You should use standard library API in java.nio.Files like this.您应该在java.nio.Files这样的文件中使用标准库 API。

public String readFileAndReturnString() throws IOException {
    return Files.readString(Paths.get(this.fileName));
}

public List<String> readFileAndReturnStringArr() throws IOException {
    return Files.readAllLines(Paths.get(this.fileName));
}

It's a bad design to return an empty string or empty list when an IOException is thrown.抛出IOException时返回空字符串或空列表是一种糟糕的设计。 Because you cannot distinguish from reading an empty file.因为您无法区分读取空文件。 You should explicitly throw back the IOException .您应该显式地退回IOException

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

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