重构这个简单方法的最有效方法是什么?

5 java refactoring

我实现了一个非常简单的方法:

private String getProfileName(String path) {
    String testPath = null;
    for (int i = 0; i < path.length(); i++) {
       testPath = path.substring(0, i);
          if ( testPath.endsWith("1") || testPath.endsWith("2") || testPath.endsWith("3") || testPath.endsWith("4") || testPath.endsWith("5") || testPath.endsWith("6") || testPath.endsWith("7") || testPath.endsWith("8") || testPath.endsWith("9") ) {
            break;
          }
    }
    return testPath.substring(0, (testPath.length() - 1));
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢整个方法,因为我认为它比必要的更复杂,尤其是if条件.

所以我想到了一种重构这种方法的方法.首先,我想到使用Regex来替换if条件,但对于这个简单的情况,是不是正则表达式有点太多了?

任何其他想法如何重新审视这个?

Mar*_*ers 12

将此模式与匹配器一起使用:

"^[^1-9]*"
Run Code Online (Sandbox Code Playgroud)

示例代码:

private String getProfileName(String path) {
    Pattern pattern = Pattern.compile("^[^1-9]*");
    Matcher matcher = pattern.matcher(path);
    matcher.find();
    return matcher.group();
}
Run Code Online (Sandbox Code Playgroud)

我认为这比你的代码更容易理解.我花了几分钟来计算你的逻辑,我必须运行它才能确定.我认为使用正则表达式很清楚代码在做什么.如果您希望可以只编译一次正则表达式并通过将其移动到类的静态成员来重用它.

正则表达式对Stack Overflow有很大的耻辱(主要来自试图使用它们来解析HTML,电子邮件地址,URL以及各种其他令人讨厌的正则表达式的不当使用的人).但是对于这种任务,正则表达式就好了.

您可能还想考虑为什么要省略0,如果这是个好主意.

  • "不使用正则表达式来解析html"成为新的"不要使用表格进行布局",人们将其视为"不要使用正则表达式,永远!" 并且"永远不要使用桌子!"? (3认同)

sou*_*els 7

矿:

private String getProfileName(String path) {

    return path.split("[1-9]")[0];
}
Run Code Online (Sandbox Code Playgroud)

希望这会帮助你.

说明.正如Mark Byers所说,数字上的Split(第一个版本,第二个版本忽略0),并返回结果数组的第一个元素.但我认为如果第一个参数是一个数字(用jdk1.6.0_20测试),它不会失败.如果路径中的所有字符都是数字(例如"2223"),则会失败.您可以使用此版本来避免错误:

private String getProfileName(String path) {

    String[] result = path.split("[1-9]");
    return result.length > 0 ? result[0] : "";
}
Run Code Online (Sandbox Code Playgroud)

正如您将在String的split方法javadocs中,它接受一个参数(正则表达式),您可以使用以下方法之一:

return path.split("[1-9]")[0]; //if you want to avoid 0
return path.split("\\d")[0]; //if you don't
Run Code Online (Sandbox Code Playgroud)

恕我直言:如果您正在寻求提高代码可读性,使用split方法比其他方法更好,


Tim*_*ddy 6

当然,你可以使用蛮力重构...但为什么不使用Apache Commons?

private String getProfileName(String path) {
    int index = StringUtils.indexOfAny(path, "123456789");
    if(index != -1) {
        return path.substring(0, index);
    }
    return path;
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ine 5

除了正则表达式:

private static String getProfileName(String path) {
    final int len = path.length();
    for (int i=0; i<len; ++i) {
       char c = path.charAt(i);
       if ('1' <= c && c <= '9') {
           return i==0 ? "" : path.substring(0, i-1); // Probably don't want that -1 !!
       }
    }
    return len==0 ? "" : path.substring(0, len-1);
}
Run Code Online (Sandbox Code Playgroud)

或者,对于Single Entry,Single Exit粉丝:

private static String getProfileName(String path) {
    final int len = path.length();
    int i=0;
    while (i != len && !isProfileTerminator(path.charAt(i))) {
    //Or (!(i == len || isProfileTerminator(path.charAt(i)))) {
       ++i;
    }
    return i==0 ? "" : path.substring(0, i-1);
}
private static boolean isProfileTerminator(char c) {
    return '1' <= c && c <= '9');
}
Run Code Online (Sandbox Code Playgroud)

原始代码中存在问题,字符串为空或以1-9开头.