string s1 = "t";
string s2 = 't'.ToString();
Console.WriteLine(s1.Equals(s2)); // returning true
Console.WriteLine(object.Equals(s1, s2)); // returning true
Run Code Online (Sandbox Code Playgroud)
这里返回相同的结果.现在,当我使用StringBuilder时,它没有返回相同的值.底层的原因是什么?
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
Console.WriteLine(s1.Equals(s2)); // returning true
Console.WriteLine(object.Equals(s1, s2)); // returning false
Run Code Online (Sandbox Code Playgroud)
编辑1:我的上述问题在下面回答.但在本次讨论中,我们发现StringBuilder在其实现中没有任何覆盖Equals方法.所以当我们调用StringBuilder.Equals时,实际上它会转到Object.Equals.因此,如果有人调用StringBuilder.Equals和S1.Equals(S2),结果将会有所不同.
Java StringBuilder和StringBufferJava 之间的差异已经有很好的文档记录,并且在StackOverflow中也有所涉及.
基本上,StringBuilder是一个非同步副本StringBuffer,具有几乎相同的接口,因为它旨在作为更快速的替代品StringBuffer.它们的API实际上是相同的,它们实际上是当前JDK中相同的不可访问的抽象类的子类.
因此,我想知道的一件事就是它们与公众无关.让两个类实现一个公共接口或甚至StringBuffer作为子类都有StringBuilder意义,允许两个类共享代码的存在.
为什么这种被迫分离呢?是不是程序员不会无意中将线程安全与线程不安全的代码混合在一起?或者它只是一个设计疏忽,现在将继承到永恒的结束?
编辑:
为了说清楚:我可以推测为什么事情是这样的,但我希望具体参考实际的决定,例如在JSR过程中.对我来说,任何可能会对某些情况产生影响的事情偶然会引起一定程度的困难.
编辑2:
两个班级Appendable完全实现的事实让我大吃一惊.可能是因为该特定界面对于大多数目的而言是无用的 - 它只能附加单个字符或准备好的对象,就是这样.在大多数情况下,它并不比两个类都是子类更有用Object.
编辑3:
那么,以下是来自半官方来源的确切问题的基本原理:
图书馆团队评估:
根据设计,StringBuffer和StringBuilder不共享公共超类型.它们不是替代品:一个是错误(StringBuffer),另一个(StringBuilder)是它的替代品.
显然,在某些情况下,缺少常见的超类型会减慢从StringBuffer到StringBuilder的希望迁移.另一方面,通过添加一个共同的超类型,我们将把我们过去的错误带入公共界面并与我们永远保持一致.这不仅会减慢迁移速度:它会使迁移脱轨.
当我查看反编译的.NET程序集以查看一些内部结构时,我注意到StringBuilderCache了多个框架方法使用的有趣类:
internal static class StringBuilderCache
{
[ThreadStatic]
private static StringBuilder CachedInstance;
private const int MAX_BUILDER_SIZE = 360;
public static StringBuilder Acquire(int capacity = 16)
{
if (capacity <= 360)
{
StringBuilder cachedInstance = StringBuilderCache.CachedInstance;
if (cachedInstance != null && capacity <= cachedInstance.Capacity)
{
StringBuilderCache.CachedInstance = null;
cachedInstance.Clear();
return cachedInstance;
}
}
return new StringBuilder(capacity);
}
public static void Release(StringBuilder sb)
{
if (sb.Capacity <= 360)
{
StringBuilderCache.CachedInstance = sb;
}
}
public static string GetStringAndRelease(StringBuilder sb)
{
string …Run Code Online (Sandbox Code Playgroud) StringBuilder是否具有JAVA中最大容量的字符限制.
StringBuilder url=new StringBuilder();
stmt = connnection.createStatement();
String sql="SOME QUERY";
rs = stmt.executeQuery(sql);
while(rs.next())
{
String emailId=rs.getString("USER_EMAIL_ID");
url.append(emailId);
}
Run Code Online (Sandbox Code Playgroud)
StringBuilder变量'url'是否具有最大容量,还是可以容纳所有内容?
应该StringBuilder.Capacity设置为最大.NET字符数,而不考虑空终止,或者在使用P/Invoke时,必须将其设置为更高,以便为空终止符保留空间.
自然的反应是它应该设置得更高,但似乎P/Invoke应该自动补偿.事实上,这实际上是在这里记录的:http://msdn.microsoft.com/en-US/library/s9ts558h(v = VS.100).aspx
这个问题的原因是大多数示例与上述文档并不严格一致.它们几乎总是被编码:
StringBuilder sb = new StringBuilder(dotNetChars + 1);
SomeWindowsAPI(sb, sb.Capacity);
Run Code Online (Sandbox Code Playgroud)
代替:
StringBuilder sb = new StringBuilder(dotNetChars);
SomeWindowsAPI(sb, sb.Capacity + 1);
Run Code Online (Sandbox Code Playgroud)
(我意识到一些API处理缓冲区大小参数的方式不同.假设API处理这是必须的常见方式,如GetFullPathName:http://msdn.microsoft.com/en-us/library/aa364963(v = VS.85) .aspx)
sb.Capacity直接在API调用中使用表达式似乎是避免不匹配的最佳实践.问题是添加+1是否正确.
环视四周.您可能会发现唯一显示的sb.Capacity + 1是MSDN文档.
当然,人们可以在谨慎的情况下使用比绝对必要的更大的缓冲区来分配,但我想知道如何做到这一点的共识.
我尝试着 :
1 string pal = "Juan 1David 1Correa";
2 StringBuilder sb = new StringBuilder(pal);
3 Console.writeline( sb.ToString(0,9) );
4 Console.writeline( sb.ToString(10,14) );
5 Console.writeline( sb.ToString(15,26) );
Run Code Online (Sandbox Code Playgroud)
但是在4行中它引发了异常.
为什么?
我正在尝试在我的java类中编写几行html,从另一个API获取一些数据.我在JSON字符串中获取数据,然后想在网页上显示一些数据.
要创建HTML,我尝试:
StringBuilder sb = new StringBuilder();
for(int i=0;i<leads.size();i++){
sb.append("<p>Name: "+leads.get(i).getFirstName()+" "+leads.get(i).getLastName()+"</p>");
sb.append("<p>Email: "+leads.get(i).getEmail()+"</p>");
sb.append("<br />");
}
fullLeadData = sb.toString();
Run Code Online (Sandbox Code Playgroud)
但最终显示的是对html标签的字面解释.有没有办法可以创建这个字符串,以便标签保留为标签而不是转义字符?
java类是一个托管bean,所以在html中我有:
<body>
<div id="display">
#{PortalView.fullLeadData}
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
其中fullLeadData是带有html的字符串.
我有一个StringBuilder累积代码.在某些情况下,它在代码块之间有2个空行,我想将那1个空行.
如何检查当前代码的末尾是否有空行?(ToString()由于性能问题,我不想使用它的方法.)
这两种方法有什么区别?
一个比另一个更有效吗?
我想也许AppendText()使用类似于StringBuilder的方法,即它使用自己的缓存而不是每次创建和追加一个新字符串,是真的吗?
谢谢.
// Reset resets the Builder to be empty.
func (b *Builder) Reset() {
b.addr = nil
b.buf = nil
}
Run Code Online (Sandbox Code Playgroud)
代码片段来自go strings.Builder中的源代码。缓冲区设置nil为而不是b.buf[:0]。nil将其设置为而不保留容量的原因是什么?
编辑:
我可以看到它Reset()可以用于 GC 底层缓冲区并允许重新使用 Builder 结构,但初始化该结构似乎是边际成本,因为它只是两个指针,而底层数组可能是更大,并且可以重复使用。我觉得应该有一个Clear()函数可以保留底层缓冲区的容量,但将其长度减少到 0,而且实现起来很简单。这让我相信没有这样做是有原因的,我很好奇这个原因是什么。