性能(JAVA)~循环中带前置和追加的字符串连接

性能(JAVA)~循环中带前置和追加的字符串连接,java,string,performance,loops,concatenation,Java,String,Performance,Loops,Concatenation,我有性能问题。是否有人有更快/更好的解决方案来执行以下操作: String main = ""; for (String proposition : propositions) { if (main.length() == 0) { main = proposition; } else { main = "|(" + proposition + "," + main + ")"; }

我有性能问题。是否有人有更快/更好的解决方案来执行以下操作:

    String main = "";
    for (String proposition : propositions) {
        if (main.length() == 0) {
            main = proposition;
        } else {
            main = "|(" + proposition + "," + main + ")";
        }
    }
我知道concat和stringbuilder速度更快,但我不知道如何使用这些方法。由于以下代码行:

main = "|(" + proposition + "," + main + ")";

提前谢谢

因此,从我可以看出,这里有三个问题:

  • 值主要在字符串前面
  • 每个值都会附加一个字符
  • 如果只存在一个值,则不应添加任何内容
  • 对于2个或多个项目,第0个项目的处理方式不同:
  • 0:“

    1:“A”

    2:“(B,A)”

    3:|(C,|(B,A))”

    通过进行一些更改,可以加快速度:

  • 与算法相反,这意味着大部分工作都涉及追加,从而允许您使用StringBuilder
  • 计算关闭
    的数量,并在循环完成后追加这些数量
  • 列表中0或1项的特殊情况
  • 通过这些更改,算法应该能够使用StringBuilder,并且速度更快

    尝试一种算法:

    int length = propositions.size();
    if (length == 0) {
        main = "";
    } else {
        StringBuilder sb = new StringBuilder();
        int nestingDepth = 0;
        // Reverse loop, ignoring 0th element due to special case
        for (int i = length - 1; i > 0; i--) {
            sb.append("|(").append(propositions.get(i)).append(',');
            nestingDepth++;
        }
        // Append last element due to special casing
        sb.append(propositions.get(0));
        for (int i = 0; i < nestingDepth; i++) {
            sb.append(')');
        }
    
        main = sb.toString();
    }
    
    int length=propositions.size();
    如果(长度==0){
    main=“”;
    }否则{
    StringBuilder sb=新的StringBuilder();
    int嵌套深度=0;
    //反向循环,由于特殊情况而忽略第0个元素
    对于(int i=长度-1;i>0;i--){
    sb.append(“|(”).append(proposities.get(i)).append(‘,’);
    嵌套深度++;
    }
    //由于特殊套管,追加最后一个元件
    sb.append(propositions.get(0));
    for(int i=0;i

    我相信这应该会产生正确的结果,但它应该给出正确的想法。

    问题是,您在执行操作时正在对字符串进行预加和追加。String和StringBuilder不能很好地处理这个问题(并提供二次性能)。但您可以使用支持在开始和结束时插入的出列来存储所有片段。最后,您可以在出列中加入位

    ArrayDeque bits = new ArrayDeque();
    for (String proposition : propositions) {
        if (bits.size() == 0) {
            bits.push(proposition);
        } else {
            // Add prefix
            main.offerFirst("|(" + proposition + "," );
            // Add suffix
            main.push(")");
        }
    }
    StringBuilder sb = new StringBuilder();
    for( String s : bits) {
       sb.append(s);
    }
    main = sb.toString();
    

    假设这是一个
    命题的数组
    ,您可以首先对数组中
    字符串的长度进行求和。为附加字符添加4,并减去4,因为在第一个元素上不使用这些分隔符。这应该是输出的最佳大小(这是可选的,因为
    StringBuilder
    是动态调整大小的)。接下来,构造一个
    StringBuilder
    。添加第一个元素。所有后续元素都遵循相同的模式,因此使用传统的
    for
    简化了循环。大概

    int len = Stream.of(propositions).mapToInt(s -> s.length() + 4).sum() - 4;
    StringBuilder sb = new StringBuilder(len); // <-- len is optional
    sb.append(propositions[0]);
    for (int i = 1; i < propositions.length; i++) {
        sb.insert(0, ",").insert(0, propositions[i]).insert(0, "|(").append(")");
    }
    System.out.println(sb);
    
    int len=Stream.of(命题).mapToInt(s->s.length()+4).sum()-4;
    
    StringBuilder sb=新StringBuilder(len);//你想要实现什么?你的预期结果是什么?@AndrewTobilko他想用一种更快的方法来提高性能。你试过插入StringBuilder吗?或者在迭代之前反转
    命题
    ,这样是否只允许追加?命题.length()
    是否可以为零?向后循环可能会使使用
    StringBuilder
    @lmiguelvargasf更容易:投票人可能已经投票了,因为将此代码转换为使用更有效的字符串构建形式实际上并不简单,因为预加和追加是混合的。他不需要反转算法
    StringBuilder.insert()
    存在。@EJP:但是使用
    insert
    无法解决这一点,因为您不会对二次运行时做任何事情。@EJP insert需要移动所有以前的输入,它可能会涉及与原始代码一样多的内存混乱。insert可能需要移动输入,但是仍然比创建所有这些字符串的原始结构要快。另一种选择是使用
    ArrayDeque
    ,这是一种循环结构,在开始插入的速度与结束插入的速度一样快。最后你可以加入所有的字符串。我要试试这个方法,谢谢你回复了所有的字符串。我要试试这个方法,谢谢你回复了所有的字符串。