StringBuffer、StringBuilder,javastringbuffer和stringbuilder
00-1010 StringBuffer和stringbuilder的区别create StringBuffer () add函数delete函数replace函数reverse函数最后总结一下,string buffer和StringBuilder是不可变的。
String:是一个字符常量,适合少量的字符串操作。
StringBuilder:适合单线程下字符缓冲区的大量操作。
StringBuffer:适用于多线程下字符缓冲区大量操作的情况。
目录
StingBuffer是线程安全的,而StringBuild是线程不安全的。
然后你往上看,会发现两者都是通过调用AbstractStringBuilder类实现的。
我们并不是说StringBuffer和StringBuilder创建的字符串是可变的。
至于源代码,直接看源代码,详细直接体现在源代码里。
在这篇博客里,我主要讲StringBuffer,因为StingBuild和StringBuffer的方法差不多,这里就不赘述了。
00-1010第一种创建方法:
string buffer string buffer=new string buffer();
当使用由此方法创建的缓冲区字符串时,它通过查看基础代码来调用此方法:
public string buffer(){ super(16);}虽然没有给in参数,但默认是数组长度为16的字符串。
看看这种将父类上传到的方法就更简单明了了:
AbstractStringBuilder(int capacity){ value=new char[capacity];}直接创建一个长度为16的字符数组。
第二种创作方法:
string buffer string buffer=new string buffer(5);
直接给出要创建的字符的长度。
底层源代码:
public string buffer(int capacity){ super(capacity);}第三种创作方法:
string buffer string buffer=new string buffer(" Xin ");
在创建时,最初会给出一个初始化的字符串。
所以,这个时候,我们要考虑它的底层存储字符串应该创建多少个数组。看源代码。源代码会告诉我们一切。
public String buffer(String str){ super(str . length()16);append(字符串);}源代码明确告诉我们,在这种情况下创建的字符串底部数组的长度是初始字符串的长度加上16。
一点总结:
当创建StringBuffer或StringBuilder字符串时,如果未给定长度,则默认值为16。给定长度,就是给定长度。如果给定了字符串,默认的初始长度是字符串的长度加上16。
StringBuffer和StringBuild的区别
公共字符串缓冲区追加(字符串str)
让我们演示一下代码。还有一点需要考虑:
public class demo 01 { public static void main(String[]args){ String buffer String buffer=new String buffer();string buffer . append( Xin _ );//string buffer . length=4 string buffer . append( Chen _ );//stringBuff
er.length = 9 stringBuffer.append("Yu_"); //stringBuffer.length = 12 stringBuffer.append("Chen_"); //stringBuffer.length = 17 stringBuffer.append("Xi"); //stringBuffer.length = 19 System.out.println(stringBuffer); }}在不停的添加下去,当数组的长度到达16的时候,要考虑一下扩容的问题,如何扩容?
老规矩,看源代码,一切都在代码里:
照着这个步骤一步一步的点进去,到达最后的源代码:
MAX_ARRAY_SIZE的长度为:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
所以最后是 0x7fffffff-8
总的来说,每次底层数组扩容为上次的2倍加2的长度。
删除功能
第一种删除字符串中指定位置的字符
public StringBuffer deleteCharAt(int index)
这个指定删除字符串当中明确的第几个索引。只删除一个元素
注意这里是索引的位置,不是第几个元素。
public class Demo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi"); System.out.println(stringBuffer); stringBuffer.deleteCharAt(4); System.out.println(stringBuffer); }}
源码其实也不难,就不重视的看了,在这主要看一经过删除操作,它的字符串长度是如何减少的。
删除字符串当中指定区间的字符串
public StringBuffer delete(int start,int end)
牢记在Java当中大多情况下,数组下标索引都是左闭右开的。
在下面的代码当中,我删除的就是"Chen_"这5个字符
public class Demo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi"); System.out.println(stringBuffer); stringBuffer.delete(4,9); System.out.println(stringBuffer); }}
和上面一样。看一眼源码,如何处理删除后的字符串的长度:
它两的底层都调用的是native本地反方,交由计算机系统完成。
替换功能
就是将字符串中其中某一段的字符串替换为其他的字符串。
public StringBuffer replace(int start,int end,String str)
public class Demo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi"); System.out.println(stringBuffer); stringBuffer.replace(4,8,"Gu_Chen"); System.out.println(stringBuffer); }}
这里也都是数组的下标索引,所以就是从0开始计数的。
替换这也同上面的一样,也需要考虑一下底层字符串的长度问题,先看源码:
反转功能
这个功能就是将原字符串玩去哪反转过来,倒序保存起来。
public class Demo01 { public static void main(String[] args) { StringBuffer stringBuffer = new StringBuffer("Xin_Chen_Yu_Chen_Xi"); System.out.println(stringBuffer); stringBuffer.reverse(); System.out.println(stringBuffer); }}
也来看一下它的源代码
最后总结一下
String的字符串是不可变的,StringBuffer和StringBuilder是可变的String:是字符常量,适用于少量的字符串操作的情况。StringBuilder:线程不安全的,适用于单线程下在字符缓冲区进行大量操作的情况 。StringBuffer:线程不安全的,适用多线程下在字符缓冲区进行大量操作的情况。在这几条总计出来的说法当中,在这再详细说明一下为什么StringBuffer和StringBuilder是可变的。
在文章上面,我展示了许多的源码,仔细观察一下,Buffer和Builder修饰的方法,它最后返回的都是this,返回了,自己,就是无论什么操作,它最终都返回的是自己。
但是有些小伙伴还是有个疑问,当它底层扩容超过它的最大值的时候,它的数组不就要换了吗?
这点确实是对的,但是在这我们要理清一个概念,StringBuffer引用的是底层数组名字的地址,而数组在需要换一个更大的时候,这个时候是数组的引用变化了,就是指向数组的地址变了,但是指向StringBuffer的地址是不变的。
我下来使用一个debug动图来展示一下,相信能更好的理解一下。
主要看控制台里的StringBuffer和value的值。我们发现StringBuffer值地址自始至终都没有改变,而value的值在到达16的时候,需要扩容的时候,就变了。这正印证了我上面所说的。
本篇博客也就到此为止了,感谢你的阅读。如果要是还是想不清楚,特别是最后的总结部分,欢迎在评论区讨论,我看到话,会第一时间共同讨论,解决问题。
这也是我重读javase基础的一个系列,比起当时初学的时候,现在看问题多了个高度,理解什么也相对轻松一点全面一些。学习起来更加偏向阅读源码来看,所以多为大家分享看源码。
到此这篇关于Java源码深度分析String与StringBuffer及StringBuilder详解的文章就介绍到这了,更多相关Java String源码分析内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。