性能(JAVA)〜循环中的字符串连接,带有前置和后置

时间:2016-12-05 01:01:01

标签: java string performance loops concatenation

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

    String main = "";
    for (String proposition : propositions) {
        if (main.length() == 0) {
            main = proposition;
        } else {
            main = "|(" + proposition + "," + main + ")";
        }
    }

我知道concat和stringbuilder更快,但我不知道如何使用这些方法。由于以下代码行:

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

提前致谢!

3 个答案:

答案 0 :(得分:9)

据我所知,这里有3个问题:

  1. 值主要附加在字符串之前。
  2. 为每个值添加一个字符。
  3. 如果只有一个值,则不应附加或添加任何值。
  4. 对于2个或更多项目,第0项处理方式不同:
  5.   

    0: “”

         

    1: “A”

         

    2: “|(B,A)”

         

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

    通过进行一些更改可以更快地完成:

    1. 反转算法,这意味着大部分工作都涉及追加,允许您使用StringBuilders。
    2. 计算结束)的数量,并在循环结束后追加它们。
    3. 列表中0或1项的特殊情况。
    4. 通过这些更改,算法应该能够使用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();
      }
      

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

答案 1 :(得分:7)

问题在于你在前进时前置并附加到字符串。 String和StringBuilder不能很好地处理这个问题(并提供二次性能)。但是您可以使用支持在开始和结束时插入的出列来存储所有部分。最后你可以加入出队的比特。

typedef void (*VF_A)(PST_A);  // Warning here: parameter names (without types) in function declaration

typedef struct ST_A_ {
    ...
    VF_A vf_a;
} ST_A, *PST_A;

答案 2 :(得分:2)

假设这是propositions的数组,您可以先对数组中String(s)的长度求和。为附加字符添加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);