连接是否有优雅的工作?

时间:2009-03-16 06:39:40

标签: java string concatenation

我正在编写一个疯狂的libs程序,用于娱乐和编程。该程序本身非常简单,但由于游戏的性质,您将用户给出的单词放入句子中,我发现自己会使用多个连接。有没有一个优雅的工作来诉诸较少的连接,甚至消除它们更高效的东西?我知道最后如果我使用连接,它将没有任何区别,但我很好奇是否有更优雅的方式来编写这个程序。

更新:我正在使用java,但如果有一个通用的解决方案来逃避连接也会受到赞赏。

11 个答案:

答案 0 :(得分:8)

一种解决方案可能是写出你的整个疯狂的libs文件并输入需要被所选单词替换的特殊标记。

  

你刚买了一个全新的$ {NOUN1},   这将是$ {VERB1}你。

然后你可以使用例如String.replace("${NOUN1}", noun1)来表示所有单词。

答案 1 :(得分:3)

您使用的是哪种语言?

大多数高级语言都有类似的内容:

String.Format("{0} {1} {2} {3}", word1, word2, word3, word4);

答案 2 :(得分:2)

我可以通过两种方式看到你完全避免游戏中的连接:

  1. 将故事模板存储为标记集合:不可变部分和单词占位符。然后遍历集合输出不可变部分和用户单词而不是单词占位符。

  2. 编写自定义打印类,使用charAt循环遍历模板字符串,输出单词而不是单词占位符。

答案 3 :(得分:2)

不是为每个单词调用String.replace或不断附加到StringBuilder,而是可以将单词放在有序数组中,并在jdk 1.4中使用String.format(在jdk 1.5或更新版本中)或MessageFormat.format。不幸的是,两者的模式格式不同。

String myPattern = "My %s eats your %s";
// get values from the user here
String result = String.format( myPattern, (Object[])myArray );

String myPattern = "My {0} eats your {1}";
// get values from the user here
String result = MessageFormat.format( myPattern, (Object[])myArray );

这是一个完整的程序,用命令行中的值填充字符串。

public class Format
{
    public static void main( String[] args )
    {
        String pattern = "My %s eats your %s";
        System.out.println( String.format( pattern, (Object[])args ));
    }
}

答案 4 :(得分:1)

你的问题有两个方面。

首先,您可能希望避免在代码中直接使用连接。然后,您可以使用运行时中的一些字符串格式化例程。这不会跳过连接,但会将它们从代码移到运行时。

其次,您可能希望更有效地进行连接。那是另一个故事。这里最重要的是为连接字符串预分配足够大的缓冲区,因为内存重新分配非常昂贵。将子字符串复制到结果字符串中通常更便宜并且是必要的恶意。

答案 5 :(得分:1)

在避免连接的一般方法方面,我没有想到任何事情。你能做的就是给自己写一些辅助类,它简化了你的串联工作。 但是我想给你的建议是不要将字符串直接连接为

String x = "Hi";
String y = x + " there!";

字符串连接的实现在Java中非常慢,因此使用StringBuffer是一种更好的做法,特别是如果你进行大量的连接:

StringBuffer myStringBuffer = new StringBuffer();
myStringBuffer.append("Hi");
myStringBuffer.append(" there!");

像这样的东西。我现在没有在编译器中检查这个,但我相信你可以自己搞清楚。

答案 6 :(得分:1)

不确定Java,但在其他语言(如PHP和Javascript)中创建数组并加入其所有元素可能会更快。

Javascript示例:

var str = str1 + str2 + str3 + "str4" + str5 + "str6" + str7;
var str = [str1, str2, str3, "str4", str5, "str6", str7].join("");

PHP示例:

$str = $str1 . $str2 . $str3 . "str4" . $str5 . "str6" . $str7;
$str = implode("", array($str1, $str2, $str3, "str4", $str5, "str6", $str7));

如果你想在每个字符串之间放置一个分隔符,这种方法最好,在这种情况下它不仅更快,而且更紧凑和可读。

答案 7 :(得分:0)

通过'避免连接'我假设你的意思是为新字符串分配空间并分配它?如果您使用的是.NET,那么StringBuilder应该对我认为有用。

答案 8 :(得分:0)

如果你有一个String需要经常修改它,使用char []数组并在完成修改后创建一个String可能会有所帮助。

答案 9 :(得分:0)

如果你愿意的话,没有连接就可以做到这一点。虽然这可能不太值得。

部分取决于您要显示结果的位置。如果它在Web或控制台上,则可以将结果直接写入输出流。

例如,如果您的模板类似于“%001跳出%002”,您可以:

1)扫描字符串以查找变量的位置。 2)在这种情况下,将字符串分解为组件列表“the”,“跳出” 3)遍历列表中的元素和结果,并将它们转储到输出中,如下所示:

PrintStream  = //get output from somewhere
for(int i = 0; i < pieces.size()-1 ; i++){
   ps.print(peices.get(i));
   ps.print(answers.get(i));
}
ps.print(pieces.get(pieces.size()-1));//last one

现在。我不知道你是否会称之为“优雅”。它可能会有点快。就像我说的那样,如果这是一个网络服务并且它变得非常流行等,也许是合适的。

如果这是一个GUI应用程序,您可以编写代码来单独绘制字符串,但这可能需要更多时间才能连接。

可以做的一件事是使用ByteArrayOutputStream并预先分配足够的空间,以便它可以包含填充的madlib而无需进行额外的分配。那也很快。

答案 10 :(得分:0)

为什么你想要避免串联,如果它的清洁度很好地排列它可能最终看起来非常好。即使你担心性能你可能不需要使用字符串构建器,我相信如果你这样做简单地说是一堆串联(即“fdsfsd”+ var1 + var2 +“dsfsdf”+“tyhty”它编译成与字符串构建器相同的东西(实际上相同并且看起来更干净)。如果你正在编写一个字符串生成器,它确实有意义大量的东西在一个循环或复杂的流动。