我正在将Java代码转换为C#.Java中的StringBuilder类似乎有比C#更多的方法.我对(比如说)Java功能很感兴趣
sb.indexOf(s);
sb.charAt(i);
sb.deleteCharAt(i);
Run Code Online (Sandbox Code Playgroud)
这似乎在C#中缺失.
我想前两个可以建模
sb.ToString().IndexOf(s);
sb.ToString().CharAt(i);
Run Code Online (Sandbox Code Playgroud)
但第三个是否会根据某人的内容而非实际内容进行操作?
是否有一种将此功能添加到所有缺失方法的常用方法?
我正在使用从.Net移植到Delphi 7 的TStringBuilder类.
这是我的代码片段:
procedure TForm1.btn1Click(Sender: TObject);
const
FILE_NAME = 'PATH TO A TEXT FILE';
var
sBuilder: TStringBuilder;
I: Integer;
fil: TStringList;
sResult: string;
randInt: Integer;
begin
randomize;
sResult := '';
for I := 1 to 100 do
begin
fil := TStringList.Create;
try
fil.LoadFromFile(FILE_NAME);
randInt := Random(1024);
sBuilder := TStringBuilder.Create(randInt);
try
sBuilder.Append(fil.Text);
sResult := sBuilder.AsString;
finally
sBuilder.free;
end;
mmo1.Text := sResult;
finally
FreeAndNil(fil);
end;
end;
showmessage ('DOne');
end;
Run Code Online (Sandbox Code Playgroud)
我遇到了AV错误.当我创建大小倍数为1024的内存时,我可以缓解这个问题,但有时它仍然会发生.
难道我做错了什么?
我用javac命令行查看了我的编译代码,每当我使用String运算符+运算符时,我就会看到,编译后的代码被StringBuilder的append()方法替换.现在我认为使用StringBuilder和String连接具有相同的性能,因为它们具有相似的字节码,是否正确?
根据KathySierra的SCJP学习指南:
必须对字符串进行修改时,应使用java.lang.StringBuffer和java.lang.StringBuilder类.正如我们所讨论的,String对象是不可变的,所以如果你选择对String对象进行大量的操作,你最终会在String池中放弃很多被抛弃的String对象
为了清除这一点,我在这里完成了String类和StringBuilder 源代码.
String的simplfied代码如下所示:
public final class String(){
private final char [] value; //Final helps in immutability, I guess.
public String (String original){
value = original.value;
}
}
Run Code Online (Sandbox Code Playgroud)
和StringBuilder的简化版本是这样的:
public final class StringBuilder{
char [] value;
public StringBuilder(String str) {
value = new Char[(str.length() + 16)]; // 16 here is implementation dependent.
append(str);
}
public StringBuilder append(String str){
//Add 'str' characters in value array if its size allows,
else
// Create new array of size newCapacity …Run Code Online (Sandbox Code Playgroud) StringBuilder bd = new StringBuilder('[');
Iterator<String> iter = names.iterator();
while (iter.hasNext()) {
bd.append(iter.next());
if (iter.hasNext()) {
bd.append(", ");
}
}
bd.append(']');
return bd.toString();
Run Code Online (Sandbox Code Playgroud)
我认为输出会看起来像[<some stuff, if any>],但它看起来像<some stuff, if any>].
到底是怎么回事?
这是一些简单的Java代码:
String s = new StringBuilder().append("a").append("b").append("c").toString();
Run Code Online (Sandbox Code Playgroud)
我用JRE 1.6编译它,我在反编译的类文件中观察到以下内容:
String s = "a" + "b" + "c";
Run Code Online (Sandbox Code Playgroud)
根据这个观察我有以下问题:
我偶然发现了有关一个奇怪的性能问题StringBuilder的append方法.我注意到似乎是一个愚蠢的错误 - 使用StringBuilder构造函数时的字符串连接(这甚至在NetBeans IDE中显示为警告).
版本1
int hash = -1; //lazily computed, also present in Version 2
int blockID = ... //0 to 1000, also present in Version 2
int threadID = ... //0 to 1000, also present in Version 2
boolean hashed = false; //also present in Version 2
@Override
public int hashCode(){
if(!hashed){
StringBuilder s = new StringBuilder(blockID+":"+threadID);
hash = s.toString().hashCode();
hashed= true;
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
在运行时期间创建了数百万个这样的对象,所以我想通过进行以下更改,它会提供一些加速:
版本2
@Override
public int hashCode(){ …Run Code Online (Sandbox Code Playgroud) 我经常遇到创建对象集合的String表示的任务.
例:
String[] collection = {"foo", "bar", "lorem", "dolar"};
Run Code Online (Sandbox Code Playgroud)
我要创建的表示:"foo,bar,lorem,dolar".
每当我遇到这个任务时,我都想知道哪种方法能够达到理想的效果.
我知道有很多方法可以获得所需的表示,但是例如我总是想知道,如果有可能通过使用for/each循环来创建字符串?
像这样:
StringBuilder builder = new StringBuilder();
for (String tag : list) {
builder.append(tag + ", ");
String representation = builder.toString();
// but now the String look like this: "foo, bar, lorem, dolar, " which nobody wants
Run Code Online (Sandbox Code Playgroud)
或者最好直接使用迭代器(如果有的话)?
假设list是一个集合(这就是它们在JDK中的表现方式):
Iterator<String> it = list.iterator();
while (it.hasNext()) {
sb.append(it.next());
if (!it.hasNext()) {
break;
}
sb.append(", ");
}
Run Code Online (Sandbox Code Playgroud)
当然,人们可以使用传统的for循环索引数组或执行许多其他操作.
将字符串列表转换为用逗号分隔每个元素的表示的最简单/最佳可读/最安全的方法是什么,并在开头或结尾处理边缘情况 …
我正在编写一个拼写纠正器,为用户提供建议.要做到这一点,我正在使用一个和两个编辑距离的单词.有四种技巧:
其中一些需要通过单词进行多次迭代,并执行诸如交换两个字母或在字符串中间添加字母之类的操作.
我知道String在java中是不可变的,并且字符串生成器中的插入可能会根据需要创建字符串的副本,所以我想知道char数组是否会使这更快.
如果我只有ReadOnlySpan切片,那么连接字符串的最有效方法是什么?
简化示例:
public class Program {
public string ConcatSpans(string longstring) {
var span = longstring.AsSpan();
var sb = new StringBuilder(longstring.Length);
sb.Append(span.Slice(40, 10));
sb.Append(span.Slice(30, 10));
sb.Append(span.Slice(20, 10));
sb.Append(span.Slice(10, 10));
sb.Append(span.Slice(0, 10));
return sb.ToString();
}
[Benchmark]
public void ConcatSpansBenchmark() {
ConcatSpans("aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee");
}
public static void Main(string[] args) {
var summary = BenchmarkRunner.Run<Program>();
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
BenchmarkDotNet=v0.11.2, OS=Windows 10.0.17134.345 (1803/April2018Update/Redstone4)
Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=2.1.403
[Host] : .NET Core 2.1.5 …Run Code Online (Sandbox Code Playgroud)