【问题标题】:Elegant Solutions to the Fencepost Problem (with Strings)Fencepost 问题的优雅解决方案(使用字符串)
【发布时间】:2011-10-15 00:14:28
【问题描述】:

我指的是将Strings与中间的某个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] );
}

删除了重新分配,但看起来仍然没有吸引力。非常感谢任何其他解决方案。

【问题讨论】:

    标签: java string-formatting string-concatenation fencepost


    【解决方案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 表示代码。它再次受到其他两个答案所具有的额外条件的额外复杂性的影响......
    猜你喜欢
    • 2023-03-19
    • 2015-10-12
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2011-03-31
    相关资源
    最近更新 更多