Fencepost 问题的优雅解决方案(使用字符串)
Posted
技术标签:
【中文标题】Fencepost 问题的优雅解决方案(使用字符串)【英文标题】:Elegant Solutions to the Fencepost Problem (with Strings) 【发布时间】:2011-10-15 00:14:28 【问题描述】:我指的是将String
s与中间的某个String
连接起来,比如用句点分隔的句子连接起来,或者用逗号连接参数列表。我知道您可以使用库,但有时这些库无法满足您的需求,例如当您想要生成要连接的短语时。到目前为止,我已经提出了两个解决方案,
StringBuffer sentence = new StringBuffer();
String period = "";
for ( int i = 0; i < sentences.length; i++ )
sentence.append( period + sentences[i] );
period = ". ";
遭受period
的冗余重新分配。还有
StringBuffer actualParameters = new StringBuffer();
actualParameters.append( parameters[0] );
for ( int i = 1; i < parameters.length; i++ )
actualParameters.append( ", " + parameters[i] );
删除了重新分配,但看起来仍然没有吸引力。非常感谢任何其他解决方案。
【问题讨论】:
【参考方案1】:似乎是一个常见问题!
Remove last character of a StringBuilder?
这会导致类似:
StringBuffer sentence = new StringBuffer();
String separator = ", ";
for ( int i = 0; i < sentences.length; i++ )
sentence.append( sentences[i] )
sentence.append( separator );
sentence.setLength(sentence.length() - separator.length());
【讨论】:
+1 非常好的解决方案,需要不断的时间,跳出框框思考:)(sb
需要替换为sentence
)感谢您的链接。
如果您已经在使用 StringBuffer,请不要使用 +
!使用第二个append
!使用 StringBuffer 的主要原因是避免 +
会创建一个额外的 StringBuffer(每次交互)。
如果sentences
为空,则会崩溃【参考方案2】:
如果你至少有一个字符串,那么:
String join(String separator, String... strings)
String s = strings[0];
for (int i = 1; i < strings.length; i++)
s += separator + strings[i];
return s;
【讨论】:
这实际上与我提出的第二个解决方案相同,只是它使用String
连接来建立结果,尽管由于其他 cmets 中概述的原因,不建议这样做,特别是由 Carlos Heuberger 制作。
现代 Java 编译器将字符串连接转换为 StringBuilder + append() 调用。尝试在类上使用 javap -c 来查看生成的代码。虽然这并不总是像手动生成的代码那样高效,但总是具有更易于遵循源代码的好处。【参考方案3】:
有一个family of functions in Apache Commons Lang that does just that。
如果非得自己写代码,我通常做这种事情的方式如下:
StringBuilder sb = new StringBuilder();
for (String sentence : sentences)
if (sb.length() != 0)
sb.append(". ");
sb.append(sentence);
此版本允许sentences
是任何可迭代的(返回字符串)。还要注意使用StringBuilder
而不是StringBuffer
。
很容易将其概括为类似于org.apache.commons.lang.StringUtils.join
。
【讨论】:
这是一个很好的解决方案,使用了我没有考虑过的扩展for
循环,谢谢。
这是一个非常好的解决方案,目前为止最好【参考方案4】:
public String join(String sep, String... parts)
boolean first = true;
final StringBuilder sb = new StringBuilder();
for(String part: parts)
if(first)
first = false;
else
sb.append(sep);
sb.append(part);
不要因为不必要的同步和“+”运算符而使用 StringBuffer,因为这会创建不必要的中间 String 对象。
【讨论】:
+1 表示 StringBuffer 和 "+" 运算符的信息,-1 表示代码。它再次受到其他两个答案所具有的额外条件的额外复杂性的影响......以上是关于Fencepost 问题的优雅解决方案(使用字符串)的主要内容,如果未能解决你的问题,请参考以下文章