如何使StringBuilder表现为不可变的

时间:2013-07-26 10:11:00

标签: java immutability stringbuilder

有没有办法只是“暂时”附加StringBuilders? 基本上我想要的是String.concat()的相同功能和行为,但是我们不允许使用String.concat()或者使用+ 连接字符串。我转向StringBuilder,但它是可变的。

例如:

StringBuilder aliasA = new StringBuilder("a");
StringBuilder dot = new StringBuilder(".");
Clausula clause1 = new Clausula(aliasA.append(dot).append("id").toString());
Clausula clause2 = new Clausula(aliasA.append(dot).append("name").toString());

我的问题是,当我构建clause2时,aliasA不再是"a",而是"a.id"

PS:我也不能使用StringBuffer。

6 个答案:

答案 0 :(得分:2)

StringBuilder的重点是它是可变的。您不被允许使用字符串连接的原因是它创建新对象,因为字符串是正确不可变的。实际上,这通常是由jvm优化而来的,并且从优化的角度来看是一个完整的非问题。所以,你所要求的是两个世界中最糟糕的。您希望基本上创建一个具有类的新对象,该类旨在使其无法执行此操作。

所以,简短的回答:不要这样做,做其他事情。在您的情况下,Formatter类可能会起作用,因为它为您提供了可以将值传递到的可重用模板。它的可读性更高。

Formatter f = new Formatter("%s.%s");
String formatted = f.format("a","id");

实际上,只写“a”+“。” +“id”也完美无缺。 StringBuilders适用于具有循环和条件逻辑的更复杂的情况。但是,像这样的简单表达式对于编译器的优化来说实际上是悬而未决的结果。我建议你优化代码的可读性,并优化需要有基础而不是过早。

答案 1 :(得分:2)

如何在Apache Commons中使用StringUtils


你可以这样做:

String a = "a";
String dot = ".";

String clause1 = StringUtils.join(a, dot, "id");
String clause2 = StringUtils.join(a, dot, "name");

OR

String clause1 = StringUtils.join("a", ".", "id");
String clause2 = StringUtils.join("a", ".", "name");

或偶然

String clause1 = buildPropertyNotation("id");
String clause2 = buildPropertyNotation("name");

// ...

private buildPropertyNotation(String propName) {
    return StringUtils.join("a", ".", propName);
}

我真的认为它可以用于任何目的。

答案 2 :(得分:1)

您尝试过:aliasA.toString().concat(...)

(抱歉,我无法发表评论)

另见: StringBuilder vs String concatenation in toString() in Java

答案 3 :(得分:1)

不会有这样的工作吗?

StringBuilder aliasA = new StringBuilder("a");
StringBuilder dot = new StringBuilder(".");
Clausula clause1 = new Clausula(new StringBuilder(aliasA).append(dot).append("id").toString());
Clausula clause2 = new Clausula(new StringBuilder(aliasA).append(dot).append("name").toString());

答案 4 :(得分:1)

字符串是不可变的,所以利用它。 StringBuilder的创建是为了构建字符串,因为字符串连接很昂贵(创建了太多的对象)。因此,您可以使用它们来实现您期望的行为:

String aliasA = "a";
String dot = "."
StringBuilder sb= new StringBuilder(aliasA);
Clausula clause1 = new Clausula(sb.append(dot).append("id").toString());
// This empties the SB, another option could be another new SB
sb.delete(0,sb.length()).append(aliasA);
Clausula clause2 = new Clausula(sb.append(dot).append("name").toString());

答案 5 :(得分:0)

好的,我所做的就是使用Jilles van Gurp在他的回答中建议的格式,定义我自己的链接方法:

private static String link(String... strings) {
        String f = "";
        String linked;
        String amp = "%s";
        String vAmp = "";
        for (String st : strings) {
            vAmp = new StringBuilder(vAmp).append(amp).toString();
        }

        linked = f.format(vAmp, strings);

        return linked;
}

我不知道它在性能方面是否是最佳的,但我的技术团队使用和阅读都很简单。