性能(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 + ")";
提前谢谢 因此,从我可以看出,这里有三个问题:
)
的数量,并在循环完成后追加这些数量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
,这是一种循环结构,在开始插入的速度与结束插入的速度一样快。最后你可以加入所有的字符串。我要试试这个方法,谢谢你回复了所有的字符串。我要试试这个方法,谢谢你回复了所有的字符串。