为什么这段代码会执行?

时间:2017-05-14 19:28:34

标签: java string

假设我有一个名为withoutX的方法,当给定一个字符串时,如果它们是x,则删除字符串的第一个和最后一个字母。

我的代码是:

public String withoutX(String str) {
  if(str.length()>0 && str.substring(0,1).equals("x")) {
    str = str.substring(1);
  }
  if(str.length()>0 && str.substring(str.length()-1).equals("x")) {
    str = str.substring(0,str.length()-1);
  }
  return str;
}

当str =" x&#34 ;?时,为什么返回空字符串("")?当str =" x"时不会出现这种情况。在第一个if语句之后失败,因为str = str.substring(1)引用了一个超出范围的索引(str的最大索引为" x"为0)?

2 个答案:

答案 0 :(得分:3)

  

当str =" x"时,情况并非如此。在第一个if语句之后失败,因为str = str.substring(1)引用了一个超出范围的索引(str的最大索引为" x"为0)?

不,因为它没有超出界限:substring的第一个(和第二个)参数可以是字符串的length()之外的任何内容,而不仅仅是length() - 1 }。 From the Javadoc

  

[引发] IndexOutOfBoundsException - 如果beginIndex为负或大于此String对象的长度。

大于,不大于或等于。

将其写成:

会更容易(也更有效)
int start = str.startsWith("x") ? 1 : 0;
int end = str.length() - (str.endsWith("x") && start < str.length() ? 1 : 0);
return str.substring(start, end);

更简单的原因是您只需检查字符串是否以x开头/结尾; String提供了在不先构造子字符串的情况下执行此操作的方法。

它更有效的原因是它不会创建中间子串。

答案 1 :(得分:0)

让我们一步一步地完成代码:

//str = "x"
if(str.length()>0 && str.substring(0,1).equals("x")) { // both true
     str = str.substring(1);
     //now: str = ""
}
if(str.length()>0 && str.substring(str.length()-1).equals("x")) { // str.length == 0. 
    //Since && does not evaluate the second parameter, everything is fine and if doesn't get called
}
return ""; //as str = ""