我被指定负责一个项目的重构,我就遇到了这样的情况
this.path = DESTINY + deploy.name() + FILE_SEPARATOR + delivery.getSystem().getCode()
+ FILE_SEPARATOR + delivery.getName() + FILE_SEPARATOR + delivery.getEnviroment().getName();
我想将其重构为这样的:
StringBuilder tmpPath = new StringBuilder();
tmpPath.append(DESTINY);
tmpPath.append(deploy.name());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getSystem().getCode());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getName());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getEnviroment().getName());
this.path = tmpPath.toString();
或者
StringBuilder path = new StringBuilder();
...
this.path.append(DESTINY);
this.path.append(deploy.name());
this.path.append(FILE_SEPARATOR);
this.path.append(delivery.getSystem().getCode());
this.path.append(FILE_SEPARATOR);
this.path.append(delivery.getName());
this.path.append(FILE_SEPARATOR);
this.path.append(delivery.getEnviroment().getName());
最快的方法是什么?
接受的答案已经解释了如何做到这一点。我想添加一些关于“何时和何时不”的细微差别。不可能用评论中的示例来解释这一点。我怀疑很多人将来可能会因为与OP问题相同的原因而发现这个问题。 我认为在问题中的情况下重构为 StringBuilder 是出于错误的原因。这是
货物崇拜编程"It is " + LocalTime.now() + " o'clock";
会导致每个“+”的字符串串联,因此时间和空间复杂度为 O(n^2)。
但是,如果所有段在编译时都是已知的,Java 会在幕后使用 StringBuilder,即使其中一些段是动态计算或格式化的,如本例中的LocalTime.now()
。它隐式使用 StringBuilder 的事实实际上是一个无趣的实现细节;重要的是它可以将字符串的总长度确定为各个字符串长度的总和,然后分配单个字符串并填充一次。
那么什么时候应该使用 StringBuilder 呢?如果您将字符串生成器传递给方法,然后追加到它,或者如果您有条件地追加 (if (example) { stringBuilder.append("...") }
),尤其是在循环中。
在您的特定示例中,使用普通连接语法与 StringBuilder 相比不会造成性能损失,因此在可读性和性能之间没有权衡。我认为,通过对原始版本进行更好的格式化,您的字符串将比使用字符串生成器更容易阅读。这有点主观,但在我的专业圈子里,这通常被认为是正确的。我将把这两个例子放在一起,让你判断。重要的是要知道为什么我们做出决定。
原代码
this.path = DESTINY + deploy.name() + FILE_SEPARATOR + delivery.getSystem().getCode()
+ FILE_SEPARATOR + delivery.getName() + FILE_SEPARATOR + delivery.getEnviroment().getName();
StringBuilder tmpPath = new StringBuilder();
tmpPath.append(DESTINY);
tmpPath.append(deploy.name());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getSystem().getCode());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getName());
tmpPath.append(FILE_SEPARATOR);
tmpPath.append(delivery.getEnviroment().getName());
this.path = tmpPath.toString();
this.path = DESTINY + deploy.name() + FILE_SEPARATOR
+ delivery.getSystem().getCode() + FILE_SEPARATOR
+ delivery.getName() + FILE_SEPARATOR
+ delivery.getEnviroment().getName();
在使用分隔符连接字符串段时,我建议使用此选项。
this.path = String.join(FILE_SEPARATOR,
DESTINY + deploy.name(),
delivery.getSystem().getCode(),
delivery.getName(),
delivery.getEnviroment().getName());