Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';重构这个简单方法最有效的方法是什么?_Java_Refactoring - Fatal编程技术网

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

Java 什么';重构这个简单方法最有效的方法是什么?,java,refactoring,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") || testPa

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

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));
}
私有字符串getProfileName(字符串路径){
字符串testPath=null;
对于(int i=0;i
我不喜欢整个方法,因为我认为它比必要的更复杂,尤其是if条件

所以我想到了一种重构这个方法的方法。首先我想到用正则表达式来代替if条件,但是对于这个简单的例子,正则表达式不是有点太多了吗


还有其他的想法吗?

我想用正则表达式。我想不出一个更简单的方法来重构它。我可能会想到更复杂的方法,但我不认为你会想要这样。

将此模式与匹配器结合使用:

"^[^1-9]*"
示例代码:

private String getProfileName(String path) {
    Pattern pattern = Pattern.compile("^[^1-9]*");
    Matcher matcher = pattern.matcher(path);
    matcher.find();
    return matcher.group();
}
我认为这比你的代码更容易理解。我花了几分钟才弄明白你的逻辑,我必须运行它来确定。我认为,使用正则表达式可以很清楚地知道代码在做什么。如果希望,可以只编译一次正则表达式,并通过将其移动到类的静态成员来重用它

正则表达式在堆栈溢出上有一个很坏的污点(主要是因为人们试图用它来解析HTML、电子邮件地址、URL以及正则表达式的各种不恰当的使用)。但是对于这类任务,正则表达式就可以了


你也可以考虑你为什么省略了0,如果这是个好主意。

< p>你可以创建一个这样的方法来放置你的if

private static boolean endsWith1to9(String a) {
        for(int i = 1; i <= 9; i++) {
            if(a.endsWith(String.valueOf(i))) {
                return true;
            }
        }
        return false;
    }
private静态布尔值endswith1到9(字符串a){
对于(int i=1;i而非正则表达式:

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);
}
私有静态字符串getProfileName(字符串路径){
final int len=path.length();
对于(int i=0;i
私有字符串getProfileName(字符串路径)
{
int i;
对于(i=0;i
我想这样的办法行得通。如果我错了,有人纠正我

private String getProfileName(String path) {
    int i = 0;
    for(i = 0; i < path.length; ++i)
    {
        if(path.charAt(i) > '0' && path.charAt(i) <= '9') break;
    }
    return path.substring(0, i-1);
}
私有字符串getProfileName(字符串路径){
int i=0;
对于(i=0;i'0'和&path.charAt(i)Mine:

希望这对你有帮助

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

private String getProfileName(String path) {

    String[] result = path.split("[1-9]");
    return result.length > 0 ? result[0] : "";
}
正如您将看到的,它需要一个参数(一个正则表达式),您可以使用以下选项之一:

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

IMHO:如果您希望提高代码的可读性,那么使用拆分方法比其他方法要好,

当然,您可以使用蛮力重构它……但是为什么不使用Apache Commons呢

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

下面是一个非常简单的单行正则表达式解决方案:

private String getProfileName(String path) {
    return path.replaceFirst("(?s)\\d.*", "");
}
模式中的模式是
\d.*
,作为嵌入标志
(?s)
。这将匹配一个数字及其后的所有内容。我们希望删除此部分,因此将替换为空字符串

请注意,
\d
也包括
0
,因此如果这是真正的规范,请替换为
[1-9]

工具书类
  • ,
    • 我的尝试:/** /** * Numeric Register Optimized Search with Null Pointer Handling. * -> No use of Regex (per requirement). :) * -> No use of Character.isDigit() (NOTE: includes characters other than [0-9].) * -> Catch and Avoid NullPointerExceptions (Oops... review other methods above.) * -> Reduce for(...; test ; ...) to while(test) by variable declaration and ++off use. * -> Include ANDed test to avoid break call. * -> Cache "path.length" in local variable (e.g. CPU register) * -> Cache "path.charAt(off)" in local variable (e.g. CPU register) * -> Replace String.endsWith(...) Method with char < char Register Method. * -> Reuse path argument to avoid another internal object reference. * -> Avoid call to substring if [1-9] not found in path. * -> Single Entry/Single Exit Happy. :) * @return path null if passed null, otherwise valid value. */ private String getProfileName(String path) { if (path != null) { int off = -1, len = path.length; final char one = '1', nine = '9'; char c; while (++off < len && (c = path.charAt(off)) < one && c > nine); if (off < len) { path = path.substring(0, off); } } return (path); } *带有空指针处理的数字寄存器优化搜索。 *->不使用正则表达式(根据要求)。:) *->不使用字符.isDigit()(注意:包括[0-9]以外的字符) *->捕获并避免NullPointerException(Oops…查看上面的其他方法。) *->通过变量声明和++关闭使用,将for(…;test;…)减少为while(test)。 *->包括ANDed测试以避免中断呼叫。 *->缓存局部变量中的“path.length”(例如CPU寄存器) *->将“path.charAt(off)”缓存在局部变量中(例如CPU寄存器) *->将String.endsWith(…)方法替换为char重用路径参数以避免另一个内部对象引用。 *->如果在路径中找不到[1-9],则避免调用子字符串。 *->单次进入/单次退出。:) *@如果传递null,则返回路径null,否则返回有效值。 */ 私有字符串getProfileName(字符串路径){ if(路径!=null){ int off=-1,len=path.length; 最终字符1='1',9='9'; 字符c; 而(++offnine; 如果(关闭loeJava

      要明确的是:您试图在第一个非零数字处剪切字符串?未知-而不仅仅是发布代码,请描述您的方法的确切功能。我和其他人可能会因为只看到代码而不说明该方法的功能而关闭。提供示例输入数据和预期结果,我们不是读心术者。啊是的,我错过了。但是Rup是对的!@Rup是的,
      testPath
      没有使用。似乎是在返回数字之前的字符串(少一个字符-标点符号?-不检查输入是否格式正确)。当然-我的意思是底部不匹配的大小写应该返回完整的字符串(或者,正如您所指出的,少一个字符)谢谢你的NoRegex解决方案。但是如果我比较这两个解决方案,我不得不承认regex看起来更好。所以我接受regex的答案。这让我想起:。请参阅Tom的答案,以获得更简单的重构方法。“不使用正则表达式解析html”是否成为新的“不使用表进行布局”
      private String getProfileName(String path) {
          int index = StringUtils.indexOfAny(path, "123456789");
          if(index != -1) {
              return path.substring(0, index);
          }
          return path;
      }
      
      private String getProfileName(String path) {
          return path.replaceFirst("(?s)\\d.*", "");
      }
      
      /** * Numeric Register Optimized Search with Null Pointer Handling. * -> No use of Regex (per requirement). :) * -> No use of Character.isDigit() (NOTE: includes characters other than [0-9].) * -> Catch and Avoid NullPointerExceptions (Oops... review other methods above.) * -> Reduce for(...; test ; ...) to while(test) by variable declaration and ++off use. * -> Include ANDed test to avoid break call. * -> Cache "path.length" in local variable (e.g. CPU register) * -> Cache "path.charAt(off)" in local variable (e.g. CPU register) * -> Replace String.endsWith(...) Method with char < char Register Method. * -> Reuse path argument to avoid another internal object reference. * -> Avoid call to substring if [1-9] not found in path. * -> Single Entry/Single Exit Happy. :) * @return path null if passed null, otherwise valid value. */ private String getProfileName(String path) { if (path != null) { int off = -1, len = path.length; final char one = '1', nine = '9'; char c; while (++off < len && (c = path.charAt(off)) < one && c > nine); if (off < len) { path = path.substring(0, off); } } return (path); }