在java中拆分字符串的更快方法然后添加到ArrayList

PML*_*PML 4 java performance split arraylist

对于一个学校项目,我被要求用Java编写一个简单的数学解析器.该程序工作正常.我用NetBeans profiler工具检查程序的性能非常好.为此,我对以下表达式的数学解析器进行了1000次循环调用:"1-((x+1)+1)*2",其中x由当前循环计数替换.花了262ms.问题是,在方法splitFormula中占用了50%的时间,我将在下面介绍:

private static void splitFormula(String formula){
    partialFormula=new ArrayList<>();

    for(String temp: formula.split("\\+|\\-|\\*|\\/"))
        partialFormula.add(temp);
}
Run Code Online (Sandbox Code Playgroud)

,partialFormula是一个ArrayList字符串.为了数值计算表达式,我需要多次调用splitFormula方法,所以我真的需要清除partialFormula的内容ArrayList- 第一行.

我的问题是:是否有更快的方法来分割字符串然后将部分字符串添加到arraylist?或者是否有其他方法可用于拆分字符串然后使用子字符串?

Jus*_*tin 7

正则表达式可以减慢速度(String#split使用正则表达式).一般来说,如果你想编写简单的代码,正则表达式是好的,但如果你想要快速代码,看看是否有另一种方式.尝试这样做没有正则表达式:

编辑:这应该是一个更好的方法(跟踪索引而不是附加到a StringBuilder):

private static void splitFormula(String formula){
    partialFormula.clear(); // since there is a method for this, why not use it?

    int lastIndex = 0;
    for (int index = 0; index < formula.length(); index++) {
        char c = formula.charAt(index);
        if (c == '-' || c == '+' || c == '*' || c == '/') {
            partialFormula.add(formula.substring(lastIndex, index));
            lastIndex = index + 1; //because if it were index, it would include the operator
        }
    }
    partialFormula.add(formula.substring(lastIndex));
}
Run Code Online (Sandbox Code Playgroud)

StringBuilder 做法:

private static void splitFormula(String formula){
    partialFormula.clear();

    StringBuilder newStr = new StringBuilder();

    for (int index = 0; index < formula.length(); index++) {
        char c = formula.charAt(index);
        if (c == '-' || c == '+' || c == '*' || c == '/') {
            partialFormula.add(newStr.toString());
            newStr.setLength(0);
        } else {
            newStr.append(c);
        }
    }
    partialFormula.add(newStr.toString());
}
Run Code Online (Sandbox Code Playgroud)

如果我们查看源代码String#split,很明显为什么那么慢(来自GrepCode):

public String[] split(String regex, int limit) {
    return Pattern.compile(regex).split(this, limit);
}
Run Code Online (Sandbox Code Playgroud)

它每次编译一个正则表达式!因此,我们可以看到加速代码的另一种方法是首先编译我们的正则表达式,然后使用Pattern#splitto split:

//In constructor, or as a static variable.
//This regex is a better form of yours.
Pattern operatorPattern = Pattern.compile("[-*+/]");
...
private static void splitFormula(String formula){
    partialFormula.clear();

    for(String temp: operatorPattern.split(formula)) {
        partialFormula.add(temp);
    }
}
Run Code Online (Sandbox Code Playgroud)