【问题标题】:"String.substring(int, int) line: not available" causes error“String.substring(int,int)行:不可用”导致错误
【发布时间】:2021-09-23 10:57:21
【问题描述】:

不知何故,我的 if 循环使用子字符串检查 .txt 文件会导致问题。没有 if 循环,一切正常。但是有了它,文本文件中的空行似乎导致它崩溃。它一直工作到文件中的第一个空行,然后我收到此错误。我该怎么办?

代码:

public class S1_Blockchain extends ConsoleProgram {

    public void init() {
        setSize(400, 250);
        setFont("Arial-bold-18");

        BufferedReader br = null;
        String line;
        
        try {
            br = new BufferedReader(new FileReader("block_chain.txt"));
            while((line = br.readLine()) != null){
                if(line.substring(0,1).equals("T") || line.substring(0,1).equals("G")) {
                   System.out.println(line);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
    }
}

【问题讨论】:

  • line.startsWith("T") 是检查字符串是否以 T 开头的更好方法。它避免了创建不必要的子字符串,但也处理了空的情况,并且更能表达意图。跨度>
  • 似乎没有人告诉你原来的问题是什么。空行没有字符(readline 删除了行终止符)。您的子字符串调用正在提取第一个字符 - 它不存在。

标签: java substring bufferedreader


【解决方案1】:

您可能还想检查空字符串:

if( !line.trim().isEmpty() && (line.substring(0,1).equals("T") || line.substring(0,1).equals("G"))) { ... }

然后您可能还想重构代码以使其更具可读性:

public class S1_Blockchain extends ConsoleProgram {

    public void init() {
        setSize(400, 250);
        setFont("Arial-bold-18");

        BufferedReader br = null;
        String line;
        
        try {
            br = new BufferedReader(new FileReader("block_chain.txt"));
            while((line = br.readLine()) != null){
                if(shouldConsider(line)) {
                   System.out.println(line);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
    }
}

private boolean shouldConsider(String line){
  return !line.trim().isEmpty() 
         && 
         (line.substring(0,1).equals("T") || line.substring(0,1).equals("G"));
}

【讨论】:

    【解决方案2】:

    除了检查您的字符串是否为空之外,您还必须检查它是否为空字符串 ("")。您可以将其检查为line.trim().legth() == 0;line.isEmpty(),但也有名为StringUtils 的Apache Utils。有一种方法 isBlank(String str) 可以一次性检查 String 是否为空或空白。这就是我的建议

    【讨论】:

    • Java 11 支持对字符串进行此测试,例如 line.isBlank()。见isBlank()
    【解决方案3】:

    因此,您测试了 empty 字符串 ""(不愉快的路径)的第一个边缘情况。

    接下来,您可以通过使用trim()(删除周围的空白)来避免有效的空情况:

    • " Trouble Centered " 这样的间隔输入变成修剪 `“Trouble Centered”(因此可能需要以“T”开头)。
    • blank 行如 " " 变为 empty 字符串 ""(这会破坏一些测试)
            br = new BufferedReader(new FileReader("block_chain.txt"));
            while((line = br.readLine()) != null){
                line = line.trim(); // remove white-spaces; blank line results as empty
                if (line.isEmpty()) {
                  // might handle or ignore this case
                }
    
                firstChar = line.charAt(0);  // expresses intend better than substring
                if (Set.of('T', 'G').contains(firstChar) { // the Set improves readability for condition
                   System.out.println(line);
                }
            }
    

    测试字符串的替代方法

    A) 单独的测试:

    • 也可以用line.isBlank() 测试一个空的(甚至不是空格)或空白(只有空格)
    • 也可以用line.startsWith("T") 测试字符串的开头

    B) 一体式(您的情况):

    • 使用正则表达式捕获所有情况:line.matches("^\\s*(G|T)")

    【讨论】:

    • @idontknowanything 很高兴,它对你有帮助,也许对未来的读者也有帮助。记住:你可以vote on answers
    • 我试过了,但显然我需要至少 15 的声望才能投票...
    • @AndyTurner 感谢您指出:零索引。
    • @k314159 如果没有 IDE,我打字很马虎。启发我修复并添加正则表达式(希望我正确地转义了空格)。
    猜你喜欢
    • 2019-11-15
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多