00:00
好了同学们啊,那到此为止吧,咱们字符串词顺里边的方法咱就说完了啊各位这个方法呢,比较多,下去之后呢,你该练练该敲敲啊,多写多练多敲,多写多练多敲啊,这个方法呢,我在这儿1234标个号是吧,我看这是多少个啊。21个任务可能比较大一,比较大一。行吧,嗯,这个呢,咱们就说到这儿吧,啊说到这儿行,那咱们再接着往下看各位啊。那再往下看的话,我们在这儿啊,嗯。建一个新的包呗,注意听课啊,Package这个包呢,我们叫做。Buffer。行啊。来我们这边呢。新建class啊,我们叫string buffer test。零一啊,String buffer test,零一走。
01:09
我们大家思考一个问题啊,在进行字符块拼接的时候。我们使用加号有什么问题。思考一下,想一想啊,给大家点时间,十几秒20秒,你想一下,就在Java圆中,我们用加号进行这块拼接,会有什么样的问题?你思考一下啊,就你思考一个问题,就我们此论已经讲完了,各位啊,现在开启这个了。这个啊。八分。啊。思考一个问题啊,就是我们在实际的开发中,如果需要进行字符串的频繁拼接。会有什么问题?
02:03
来,如果你要是注意听上午的内容,你现在这个结论应该是可以拿出来的,对吧,因为呀,Java中的字符串拼接一次。啊,加入了字符串是不可变的。是不可变的啊,因为加文中的字符串是不可变的。每一次拼接都会产生什么新字符串?明白吧,Java,因为Java字符串是不可变的,每一次拼接都会产生新的字符串。这样会占用大量的什么方法区内存?啊。这个造成什么呢?内存空间的浪费,润S1S吧,对吧?哎,等于什么呀,等于字符串ABC。那S加等什么呀,哎哈,好各位。
03:04
那现在导致就这么两行代码就找导致什么,各位好好思考一下。导致什么?啊。就以上两行代码就导致在方法区字符串常量池当中。创建了三个对象。哪三个呀,哪三个呀,ABC对吧,还有啥呀哈,还有你拼接完的ABC hello。它导致的就这三个对象在那个。创建。如果说你你就就想说一下啊,如果说你以后开发你遇到了频繁字串拼接对吧,那就不太合适了啊,不太合适了来比如说for循环对吧?哎,String类型吧,S是个字符串,这个字符串是个空串对吧?For循环你说int类型I等于零是不是啊,I小于什么呀?哎100I干啥呀?加加你每循环一次干啥呀?S加等什么呀?哎加等I。
04:09
那你这个时候大家想一想,你你你你你你这个对象该有多少多少啊。啊,你会创建多少个对象啊?多了吧。是不是这是这是不是进行字符串拼接啊。这个代码可以换成另外一种写法,S等于S加I。对吧,你S不是字符串吗?字符串加号,这个加号在这做字符串拼接啊,拼接又产生一个新字符串对吧?然后循环下一次又产生一个新的字符串。对吧,哎,那就会导致什么呀,我们这个。空间的浪费啊,空间的浪费。是吧,哎,这这。这是多少个字符串字符串?是吧,这是一个字符串,两个三个四个,你看最初是这样的一个字符串吧,哎,然后再加等式零一这这样的字符串啊,又一个吧,哎,一个两个三个四个,它不是在原先基础之上往后加,你明白吧,它这个导致的这个问题是什么呢?就是很恐怖啊,很恐怖啊,所谓的恐怖是什么呢?就说呀,你这有个方法区。
05:19
明白吗?方法区,你这个方法区里边呢,有一个叫什么字符串常量池,字符串常量池,而你这个字符串常量池的这个东西。在这怎么着呢?哎,你有一个字符串对吧,哎,零。由于你再往下呢,你出来一个加个一,所以呢,这个就会新建零一,它并不是说。在这一块,嗯,不创建它,而是在原先的基础之上往后加一个一,它不是这样做的,各位明白吧,就是你只要拼字无创,它就会产生新的,因为我们曾经说过一个问题,什么问题?字符串在Java圆中一旦创建,它不可变零,一辈子就是零,它不能变成零一。
06:01
啊,它不能变成一,如果是零一的话,你得新建,对啊,你再来一个就是又新的012对吧?啊,你再来个就是又是0123,它是这样的,所以就导致呢,我们这个呃,空间大量的这个浪费啊,那有同学说老师那像这种情况下,我们以后如果万一要进行频繁的字符串拼接的话,我们应该怎么办呢?哎,需要用到我们Java语言当中的另外一个类型啊,这个类型叫string buffer啊叫string buffer来这个只是一个体验程句,各位啊,体验程啊,这个会给。会给什么呀,方法区字符串常量池带来很大的压力啊,这样做这样做会让什么呀,啊Java的方法区。会给。Java的方法去字符串常量池带来很大的压力啊,很大的压力,好了,那么这块呢,我们用谁呢?在这儿呢,给大家提一下吧,Class啊,这个class我们叫死顿八分啊T02。
07:08
嗯。怎么个情况?如果以后需要进行大量字符串的拼接操作,建议使用JDK中自带的什么呀?Java language language包下的有个类,这个类叫什么?叫string buffer,还有一个叫Java language string builder。这两个都行啊,都行来PSVM。打开我能帮助文档看一下吧,找找啊呃,往这拖一下看一看,它除了string之外,还有叫string buffer string builder。对吧,Buffer buffer。是不是?哎,0B法啊,大家看构造方法无参的对不对?哎,构造方法是有参的是不是啊,这个构造方法是你看可以指定指定容量吗?哎,它底层是个什么东西啊,这是啊,我们可以看看源代码吧,是不是轮八的底层到底是个啥?
08:08
嗯。来看看啊,它是构建一个其中不带字符的字符。字符串缓冲区初始化容量是16个,16个字符寸八分。它的初始化容量是16。我们可以看看啊。呃,准八分啊呃准八分,我们拗一个准八分。这是个无参构造,我们可以点过去看一下。它这个位置掉了super负力构造方法是不是传个16进去啊,他调负力构造方法,负类构造方法是这个。对吧,好,大家看他拗了一个bit是吧,是不是把这个东西传进去了。底层是个什么数组啊,这是。数组是吧。是吗?啊。你看。
09:02
看源代码会看吗?会不会看同学们能不能给个回应啊,来这不new一个spring buffer吗?创建一个带有什么呀?字符的一个字符串缓冲区默认出装容量是16嘛,点过去。它的构造方法,你看是不是16啊。不。不会看源代码,同学们,我问大家一个问题,你们会点不?你们想看这个方法能点不能,不能点,按住CTRL键能点不能,不能点过去,咱先说这个问题,你这个会不会?就看到什么,你想点过去能点吗。你是方法,你点过去它就是定位到方法,你明白吗?如果你点的是这个类名,这个类就定位到这个类上面了。看见了,我觉得你得先会点啊,你得先会点,你不会点不行,有的老师点这个,你点这个干啥呀,点这个你你点不过去啊,是不是你调方法,你就点一下,点一下它会定位到方法,你点这个类的话,它会定位到这个类,是不是按CTRL键你点过去是不是点走,你看这边是不是调负类的构造方法呀?哎,你看走一个啊,它副类是谁?傅雷有个叫abstract string builder,你看有一个抽象的string builder是不是这是一个构造方法,大家看构造方法这个位置传了一个什么呀?Capacity单词翻译过来是容量吗?
10:18
是不是啊,容量啊。你看这个构造方的作用是什么呀?是创建一个什么抽,呃,创建一个string builder对吧?哎,以什么以这个指定的容量啊,以这个指定的容量去创建一个build对象啊,那么这个capacity底层往下的时候是不是传数组啊,好,你看这个数组传过来,这个是你看这value是个数组,好通过这个大家得出个什么结论,是不是我们往这个string builder里边放东西的时候,因为我们要进行字符串拼接嘛。实际上他是把这个东西放到这个。打法的什么里边的。各位,你想过这个问题吗?就相当于底层是个什么,各位啊。
11:02
大家简单说一下吧。底层它是一个数组。而且是个数组。啊,就是这个死。Buffer底层实际上是一个BAT数组。是个bad数组啊,往这个string buffer里面放东西,实际上是往BY数组里面放啊,往什么往这个叫做。哎呀。往我们的STRING8份中放字符串,实际上是放到bet数组当中了。啊,白素当中的另外润八分的初始化容量是16。
12:05
啊,是16。那它怎么扩容的呢?它这个string buffer里边有个方法,我们研究一下,有个end什么意思,你看这个方法是不是都叫A呀,是追加吧。是不是追加呀,来string buff分啊,点追加我们追加一个字符串进去啊A,然后接下来我们STRING8UFF分再去追加一个什么呀B。哎,我们string buff法再去追加。D对吧,哎,往下追加,那么这个追加方法我们可以点过去研究一下。他追加的时候掉的是负类的,追加方法看见了吗。Super不是负类吗?负类的追加你看点过去,它是不是把这个字符串传进去了,它是怎么追加的?好,大家看这是怎么追加的。研究一下啊,大概说一下,大概说一下啊,这个是string是是不是传过来那个字符串啊,然后点Les吧,是不是len啊。
13:05
这个单词是什么意思啊,比如说确保确保容量吧。是不是确保确保容量啊。他确保容量是做了什么,我们可以点过去啊,看一下看一下。嗯,好,大家看,嗯,哎,看这个单词认识吗。我们刚学过吧。点copy of可以点过去看看底层有没有掉这个,这个学过吗?这个有没有学过?这是什么东西?各位给个回应。这个是不是数组的拷妹?数组拷贝是不是扩容?对吧,他为什么会扩容啊各位。啊。他为什么要去扩容,你看啊怎么走的啊,这块是不是string buffer掉pad是追加。对吧,追加拼字符串啊,这是来写上创建一个。
14:05
初始化容量为16的。数组。我们叫做字符串缓冲区对象啊,自带16个,然后这是什么,是拼接字符串。注意啊,以后拼接字符串一字符串统一调用什么?呃,Pen的方法明白吗?你看它不止可以追加这个。字符串啊,它还可以追加别的。你看看这个是不是可以跟波跟char对吧,还可以跟double跟float,这个方法是不是这个名字很好记,参数可以随便传,这叫方法重载吧,哎,拼串啊,来string buffer点什么呀,Ipad拼串,你再拼一个什么呀,哎,拼一个这个嗯,比如说3.14是吧,哎,然后呢,String buffer,然后点什么呀?哎,Aend去追加什么呀,哎,我们的true啊,或者是string buffer去追加什么呀?哎,我们的这个嗯。
15:15
比如说100L是吧?哎,这是不是long类型的数据啊,哎,追加追加之后呢,输出对吧?哎,String buff分点什么呀?To是不是啊,输出这个它其实会自动掉toth string,这个toth string其实你不写它也会掉啊,Toth string twoth string的意思表示把这个string buffer转成字符串啊。是不是,哎,你输出一下,你看它是不是一个字符串。叫做abcd3.14,你看这个字符串啊,从这个位置开始,到这个位置结束,这是它拼的一个字符串,就以后拼接字符串的时候,大家使用apapapa追加。明白吧,不要使用咱们的呃,加号加等这种方式去累计,你加等这种方式会导致什么呀,我们字符串的对象频繁创建,但是你的string buffer这块呢,你用apad,你你点过去,你看看它底层怎么做的APA是吧,再往下是不是它继续掉了负类的APA方法,那APA方法是不是就是追加的意思啊,Ad就是追加啊来你看这块有个确保容量是不是你点过去就知道了。
16:14
点过去发现什么呀?哎,发现我们这个方法在底层啊,它会进行数组的一个拷贝,那数组拷贝你点过去底层调的是C层,点every copy是吧?哎,Every copy表示要扩容,为啥?因为它默认出厂量是16嘛。是不是哎,默认出装容量是16啊,APA是追加的意思啊,APA是追加的意思明白吧,Ipad以后追加字符串都用这个ID。它底层满了会自动扩容啊。啊判的方法底层,啊判的方法底层在进行追加的时候啊,如果如果满了,如果BAT数组满了啊会自动扩容。
17:03
会自动扩容啊,会自动扩容,有同学说老师不对呀,他这个死顿八份底层,你刚才说它是个bad数组,那这个死顿呢。String这个东西它底层不是个BA数组吗?点回去看一下string这块是不是一个BAT数组,是不是也是啊,但是大家看这个BAT数组跟我们这个BAT数组的区别是啥?有同学发现了吗?发现了吗?有什么区别。各位。好好想想。点过去,你看这个BA数组。哎,和这个。String builder,它的数组的区别是这个前面没有final,诶,这个string前面有个final。Final是啥意思,各位?啊。这个final修饰这个变量是不是这个变量指向这个对象之后就不能再指向别的对象了。
18:04
啊。你现在知道它为什么,为什么字符串不可变,而词寸八分是可变的吗?什么原因?为什么t string buffer是可变的?因为t string buffer它这个类,它的副类是abstractt string builder,而这个abstractt string build里面是个bad数组,这个bad数组没有被final修饰,而你的string这块BY数组被final修饰了。有的老师我还是不太理解,这个修饰跟没修饰,修饰跟不修饰有啥区别呢?啊。来这个不保存了啊。什么意思呢?就相当于是说你这里有这么一段代码。对吧,然后这个value是不是指向一个BY的数组啊,来这个BY的数组呢,我就画一下啊来走走。走啊走。好,那这块是什么呀,是假如说AC好了,那你现在这个地方的一个内存地址是0X11。
19:11
那么接下来这个Y6这块是不是就等于0X11,好,大家思考一下,想想。谁等于0X11。是这个意思啊。这个Y6是不是就等于0X11,那0X11这个BY的数组是不是就指向它了?对吧,指向这个数组吧,好各位,那假如说我在这建立一个新的数组。我建了个新的数组啊。这是个新的数组,各位。我这个新的数组是不是一个新的对象?对吧,容量更大呀,是不是,哎,我这是一个新的对象,各位,那么这个新的对象,它这个位置的一个地址是0X25。那么这个0X25,大家思考一下。我们能不能再让他?
20:02
Value指向这个对象。能不能?能不能就是说你现在指向的已经是这个对象了,这个位置是被final修饰的,是不是就意味着我这个不能再指向别的了?就是我这边的value是不是指向它,这根线就不能断了,就永远指向它,而且大家学没学过数组有个特点,数组长度一旦确定能改变吗?来同学告诉我,数组的长度一旦确定能不能变化?数组长度一旦是确定123455个长度,那我问你这辈子它这个数组就是五个长度,并且final修饰的这个东西,它一旦指向这个对象,就没有办法再去指向别的对象了。那所以字符串它不能变,但是你通过原代码的一个分析发现这个abstract string builder这个东西,它里面是个bad数组,那么这个bad数组呢,它前面没有加final,你明白吗?没有加final,它没有加final有什么效果呢?我们把这个拿过来啊,大家好好看看,它如果没有加final的话,它的代码就是这样,它这块呢,可能是等于什么呀,叫做0X11,那么这个0X11现在是指向谁的,指向这个对象。
21:12
对不对,那我问大家个问题,如果说我们这边满了满了的话,在这儿是不是它底层会进行一个大的数组的创建,它会创建一个比较大的数组,然后把这个拷进来,拷进来,拷进来拷进来拷进来对不对?然后接下来他是不是让这个value这不再保存谁啊,0X11让他去保存一个0X多少啊,0X25,而这个0X25又去指向谁,又去指向了这个对象。对不对,它就指向这个对象啊,他这个对象就不再指向了。这个这个就被垃圾回收器释放了啊,垃圾回收器释放他释放谁啊,他释放这块空间,他把这个对象就咔嚓啊,就抹掉了,各位啊,抹掉了啊,这样的话,在内存里边是不是只需要留这么一个对象就行了。如果说你这个满了,我们是不是还需要在这里。
22:04
再去创建一个更大的数组啊,对吧,然后把这个东西是不是再给他一个一个一个一个一个一个拷进来,拷进来拷进来拷进来拷进来,然后让他去指向什么呀,这个对象对吧?不再指向这个对象了,这个是不是就被被垃圾回收器回走了回呃这个回收了这个这个对象。对吧,哎,所以我们现在的尺寸底层实验原理是这样的。那这样呢?我不知道大家有没有听明白啊,有没有听明白,就原先啊,就是如果是字符串的话,它就会产生什么呀,新的对象,如果是string buffer的话,它就不会产生新的对象,它不会产生新对象啊,因为之前的对象都已经被垃圾回收器回收了啊,垃圾回收回收了,那么我问大家问题啊,磁润八块在使用的时候怎么优化各位。如何优化string buffer的性能?不是双引号都占地方吗?
23:04
哎,这个这块没没问题啊。新增的那个也会在内存中占停,不会不会那个会被释放掉,BY数组会被释放掉的。BY的数组会被释放掉啊。他这是一个bad数组,没有产生那种那种字符串,新的字符串。是双引号的地方都占地方,这句话是对的。但是你使用string buffer的话,它底层就不是你想象的拼成一个新的字符串,你说A对吧,然后呢,再来一个什么呀,AB。不会出现这种情况,如果你使用string buffer的话。这个能释放啊,你final修饰了吗?各位,这个。那个那个谁,那个伟斌。啊中的ABC也占定,那你这没办法呀,那个baby你想干啥呀?你想这个空间都给他省了是吧?那不可能啊。
24:02
那不可能,那怎么可能呢?你不写代码了呀,是不是你这你就别太抠了啊,太抠了,你说这这个东西,你这个肯定占占空间,你你没办法,这个是没办法的,这个是解决不了的啊。嗯,那string里保存的字符超出BAT取值范围呢?超出BA的取值范围,BAT有取它有取值范围吗?给给你定取值范围了吗?他没定取值范围啊。没定啊。他定STRING8分的这个这个范围是16,如果超16它会扩容。超过16会自动扩容,那如何优化?八各位性能怎么提升提升上来。在创建什么顿八分的时候,尽可能尽可能啊给定一个初始化容量。
25:00
明白吧,最好减少底层数组的扩容次数。啊,预估计一下。预估计一下啊,给一个大点的初创容量啊,给一个大一些的初始化容量。你将来在面试的时候,如果说你你能把string buffer底层出装容量是16说上来,另外你可以把这个string buffer的优化这块,你能跟面试官说上来,他会认为你是一个有三年或者四年经验的软件工程师,而不是一个小白啊,所以这种东西其实看的看源代码其实还是很有意思的。还是很有意思的啊,还是很有意思的,那就看大家看不看是吧,但这个看的话确实是有点太太费太烧脑太烧脑啊太烧脑,呃,所以这块呢,我就点过去,我只说重点,我也没没怎么给你讲啊,我怕你听不懂啊,听不懂你可能会产生厌学啊A,你看追加是不是,哎它底层是不是APA呀,哎,你看APAA这会怎么着啊,哎,追加呀,确保容量啊,那确保容量这怎么办呀?哎,这边是不是就every copy啊copy你看是不是就是every copy呀,对吧?哎,就开始扩容了啊扩容拷贝了啊拷贝了。
26:14
呃,最好给定出刷容量啊,能不能呢?大家看这里有没有这样的构造方法,大家看除了这个无参构造,是不是还有个有参数的构造方法,这个有参构造,你看构造一个不带字符但具有初指定初出化容量的字符串缓冲区是不是啊,你可以指定一个初始容量。啊,你比如说在这儿。八分,哎,这这个词有点意思啊,来new一个什么呀,哎,STRING8分啊,然后指定一个什么呀,哎,比如说100对吧,这是指定初始化。容量的磁string buffer对象啊,字符串缓冲区啊,这叫字符串缓冲区对象底层是一个bad数组啊,然后呢,点班追加对吧,追加的不错对吧,Hello。
27:05
对不对b.a追加,追加一个word。啊,Word是吧,哎,点pad追加啊嗯,Hello,然后呢,点ipad追加,追加一个什么呢,我看看啊。呃,追加一个word吧,就追加一个KT吧,啊好了,那这样的话我再输出啊,输出的时候自动会掉它的to string方法,这个to你可以不写,不写它会掉的啊,它会掉的来走一个。但如果你给的容量太大,注意啊,你给的这个容量如果太大的话,嗯,追加没那么多的话,其实也比较浪费,其实我觉得就是给一个合适的初始容量啊,就关键关键点啊,关键点在哪儿,给一个什么呀,给一个合适的初始化容量啊,可以提高程序的执行效率啊,执行效率。
28:03
行了,这是关于我们死顿八分的一个内容。
我来说两句