2017-05-14 95 views
-1

假设我有一个叫做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; 
} 

为什么这个返回空字符串( “”)时,海峡= “X”?当str =“x”在第一个if语句之后失败时不会出现这种情况,因为str = str.substring(1)引用了超出边界的索引(str =“x”的最大索引为0)?

回答

3

岂不情况下,当海峡=“X”后的第一次失败,如果语句,因为海峡= str.substring(1)引用了一个超出边界的索引(str =“x”的最大索引是0)?

没有,因为它不是出界:的substring第一(和第二)参数可以是任何东西字符串的length(),不只是length() - 1From the Javadoc

[抛出] IndexOutOfBoundsException - 如果beginIndex为负或大于此字符串对象的长度大。

这大于,不大于或等于。


它会更容易(和更有效)到写为:

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提供了一些方法来做到这一点,而不是首先构造一个子串。

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

+0

'str == 0'? – Andreas

+0

另外,'? :'具有最低优先级(除了'=')优先级,所以永远不需要为条件加上括号,但通常需要将括号括起来。 :'构造,即你需要'str.length() - (str.endsWith(“x”)?1:0)'。 – Andreas

+0

@Andreas错字。固定。 –

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 = "" 
+0

OP询问为什么'str = str.substring(1)'没有失败。你没有回答这个问题。 – Andreas