00:00
嗯,关于下划线使用的限制说完以后,那我们呢,这里边儿,呃,从语法层面的几个改变呢,我们就说完了,有接口的私有方法,这个钻石操作符的一个使用,升级串语句的一个改变,下划线的一个使用,这呢,我们从语法上面的几个改变为代表性的就说完了,当然了,除此之外呢,语法上还有很多细节的一些变化,大家下来呢,可以再去做一个学习和一个阅读。啊,那接下来呢,我们来谈一谈在API这个层面呢有哪些变化,那首当其冲的话呢,我们就要提一提string啊,因为string呢,应该是我们在开发当中必不可少的一个类了啊,用的呢简直太多了,所以呢,我们首先来谈一谈这个string啊有哪些变化。那这个变化的话呢,应该是非常的有代表性的啊,那这呢,在官方提供的feature gp254当中提到了关于string的这个变化。好打开我们看一下,那我们看哪呢,在下边的话呢,它有一个叫motivation,还有一个description,呃,Motivation呢,动机其实呢,就在说明我们为什么要变这个string。
01:08
啊,然后呢,描述就是我们要怎么去用啊,变了以后呢,怎么去体现的。好,那这呢,先以最简单的一句话告诉大家,这个string变什么了?String呢,以前我们在存储它的时候呢,底层很显然或者大家呢,都应该知道的,使用的底层是差型数组啊,存储string的这个结构。啊,那也就是说我们说的呢,叫做字符串啊,这就是一个串。啊,一看到这个符号的话呢,大家其实并不陌生啊,夏天的时候呢,这个在外边儿呢,就天天能够看到这个这个东西是吧,在外边晃,晃过来晃过去啊,然后还闪灯啊,他那卖的叫羊肉串。啊,这一块呢,上面是一块羊肉啊,拿一个这个呃,签子给它穿起来,这叫做羊肉串啊,全世界的人民呢,都应该能看得懂啊,这个中文呢,是象形文字,那string我们说叫字符串,那就意味着它每一个位置呢,这都是一个字符,所以呢,这就叫做串。
02:10
所以呢,我们以前呢,说string底层呢,是使用的差型数组进行存储的,那感觉是非常的合理的,就是一个位置是一个差,总体来呢,就是一个叉型数组。啊,非常的好理解,那现在呢,在扎九当中,我们说底层结构变了,改成了子节数组。啊,你可能感觉哇,为什么要做这样的改变呢?那我们现在来看一下官方文档的这个说明啊,这呢,我就没有再使用其他的这个语言去做描述了,因为他说的呢非常的清楚,我就把它呢直接粘过来了,好我们一起来看一看啊。说the current implementation of the string class stores characters ina char AR说呢,这个string这个类啊,来存储字符串字符的啊,这个string这个类呢,它的一个呃,当前的一个呃,实现啊,或者当前它的一个代表是差型数组。
03:07
也就是我们所谓的哈,以前呢,使用底层差形数组来进行存储,说呢这个差形数组啊,它是呃,使用的两个字节,那两个字节呢,意味着就是16个bit是吧?哎,对于每一个字符来讲呢,都是使用了两个字节。啊,下面一段话。嗯,是在这儿说的哈。他这说的是什么意思呢?就是说嗯,通过我们大量的这个在堆空间当中啊,就是通过我们这个很多不同的应用程序啊,把这个数据呢,集合在一起啊,我们的一个统计发现呢,在这个对空间当中啊,哎,我们很大一部分的这个成分呢,都是这个string。啊,既然都是string,那我们呢,就有必要呢,对这个string呢啊,进行一些这个重点的关注啊,结果我们发现呢,它底层都是用的这个差评数组进行存的,下边说到了啊呃,这个。
04:00
这个string的这个对象啊,它包含的啊,啊说多数情况下呢,这个string对象包含的呢,发现它都是一些拉丁的一些字符,就像咱们现在看到的这个abcd啊是吧,还包括像其他的一些这个拼音文字啊,它都属于这种拉丁字符,而事实上呢,这种拉丁字符的话呢,它只需要一个BAT呢就可以存储了。啊,那因此的话呢,呃,就意味着呢,我们这个string底层的用的string还特别多,当然string里边呢,这个拉丁字符又特别多,那我们还用两个字节去存储它就意味着呢,我们浪费了一半的这个空间。啊,一半的空间呢,是啊,Unused的。啊,这个事儿呢,说的比较清楚哈,啊,所以呢,基于这样的一个目的,我们就希望做一个改变,改变成BY数组。啊,那改成这个BY数组呢,很多人肯定会有这个担心了啊,因为咱们知道一个中文的中呢,是一个字节绝对盛不下的,那怎么处理这个问题呢?他有办法啊,就是使用BAT字节数组的同时呢,我还使用一个叫coding flag啊去标识一下到底应该用什么样的编码集啊去存储这个数据。
05:14
下边呢,就是它具体的这个处理的方案了啊。好,大家看一下,呃,我们呢,提议说呢,去change它内部的这个结构是吧?呃,从这个UTF杠八,呃UTF-16这样的一个差型的一个RA啊,改成一个BATRA啊相当于是差型数组改成了BA数组了啊,同时呢,我们再加上一个叫coding flag,避免呢,我们像中文这样的呃字符呢,是使用bad数组是不合适的问题。啊是这样子的啊,这个UTF-16,这个大家呢,不知道清楚不清楚啊,这个UTF杠八的话呢,应该大家都比较常用了,这个UTF杠八的话呢,我们表示一个字符,它其实呢是一个动态的过程。
06:00
呃,我们的一个字符,其实它可以是一个字节,其实就像abcd一样啊啊,它也可以是两个字节啊,也可以呢,是用三个字节来表示的一个字符啊,像我们这个中文的这个呢,其实都是用三个字节来表示的,而这个UTF-16呢,它呢就非常明确的一个差啊叫做一个字符就明确的用两个字节。两个BA啊,那不管你是abcd谁,在UTF-16当中,它也是两个字节。啊,也是两个字节,这个一杠16呢,大家也可以在我们这个idea当中呢,进行设置哈,比我们进来这个设置以后,大家呢,去输入叫file啊coding。啊,在这呢,我们这我之前用的都是UTF杠八了哈,你也可以看到有UTF-16这样的这个选择啊,刚才已经说过了,UTF-16当中。不管你是拉丁文还是中文,都是用的两个字节。那这呢就提到了上面,这不说浪费了一半嘛啊,因为大部分的这个词string里边呢,都是这个拉丁纹啊,所以浪费了一半空间,那现在的话,我们改成PA的这个字节数度以后呢,我们还需要再配上一个叫coding的一个flag啊去表示一下,那这个新的字符串的话呢,啊,它将存储这个字符啊,Include说它呢,存储的这个标准呢,要么呢是SO8859杠幺或者是拉丁文啊,那这个时候呢,它就使用的是一个BAT了。
07:28
或者呢,使用的U矿16啊,但这时候我们需要指明一下,你这个including这个flag啊,就是U矿16了。啊贝的胖啊,这个当前的这个组就是我们看一下呢,你如果是CD这样的,我们就用它一个字节搞定,如果不是啊这个abcd的这样的一些了,像中文我们就还是用UTF-16,那就用两个字节啊来表示一个字符。啊,说the including flag说这个including的,它这个旗帜是吧,这样一个变量呢,它就能够来标识我们应该用哪种编码集,或者叫字符集。
08:02
好,说的呢,非常清楚哈,那我们来看一下啊,事实说话,在我们这个JDK8当中呢,嗯,咱们之前呢,应该是写过这个string哈。啊,比如在这吧,我有这个视频,大家点开。好点开以后的话呢,在我们这个JDK8当中,咱们这个底层就是使用的差型数组来存的,然后呢,我们看一下这个JK9。嗯,然后这有个string我们打开,哎,大家往这看,这呢就改成了叫that数组了。诶改成PA的速度,就是我们刚才看到这样的一个官方说明啊,它的一个具体的体现啊,嗯,那其实对于用户来讲的话呢,你是感受不到他有任何的不同的啊,你该怎么用还怎么用,只是呢,它底层这个结构呢变化了。哎,那也就意味着呢,大家呢,去答这个问题的时候啊,这时候我把这个题目呢,写在这啊说JDK8级之前。
09:04
哎,我们这个string。哎,这个我直接就呃在这写这样的一个问题吧,啊有一个什么样的面试题呢,就是这个string和这个string buffer,还有这个string builder啊,他们三者的异同,其中呢,有个点我们必须要提的就是string,哎,我们提到说它的底层是使用啊这个差型数组存储。啊,但是你之后再说这个问题的时候呢,你就要指明它是在JDK8和之前的这个版本当中使用的是它的存储啊,那JDK9中啊,它呢底层。哎,使用,哎,我们叫BA数组,哎它呢加上一个,我们刚才看到了哈,叫哎,Including the flag,哎来指明它是用什么结构,这个呢,你就不用加了啊,我这说明它呢是如何来做这个事儿,那底层结构呢,它就是用的be数组。啊,拜的数组。行,那既然这个string呢,做了一个改变了,那很多同学呢,自然而然的就会想到这个问题,那string buffer和string builder哈,原来呢,咱们说它也是用的差型数组存的,那现在他们有没有变化呢。
10:12
还是来看这个官方文档,我们往下走,在这儿呢,说的非常清楚啊。说这个基于这个string的啊,这个类像这个abstract abstract string builder啊,像它下边呢,有具体的像string builder和这个string buffer,他们呢,也是做了一个同样的一个改变。哎,那说的很清楚哈,那也就是在我们这个九当中,Ctrl shift t,大家呢,可以去输入一个叫string buffer进来以后。啊,这里边没有了是吧,找它的父类啊,负类里边我们发现也是用的that数组啊,那接着呢,我们在ctrl shift t找一下string builder。哎,String build呢,也是得看它的父类了啊,嗯,同样的用的是at数组。
11:02
哎,用的better数组,好,那通过这个呢,我们就说明的很清楚了啊,也就是说呢,对于我们这个buffer builder来讲,他们呢,也是这样子变化的。哎,也是这样的变化的啊,那这个面试题的话呢,呃,大家呢,其实讲了这扎va球以后,你就可以答一些它的变化了啊,原因是什么,为什么要改,刚才呢,我们通过这儿呢,已经说的非常清楚了,如果单纯的看这一道面试题的话呢,怎么去答,我们稍微呢再给大家说一说啊,那讲到这个,哎,Stream stream buffer和string builder的时候,它们的存储结构啊是一样的。嗯,而且呢,他们一变都跟着变了,那除此之外呢,他们这个区别是什么,我们呢,就是额外的多说两句啊,那string的话,我们上来它明显的特点呢,叫做不可变的啊字符序列。就是只要呢,你对这个字符串重新赋值。啊,修改它的值都得呢,去重新开辟一块内存空间,而spring和builder呢,他们明确的就是可变的字符序列。
12:08
啊,这是呃,这俩跟它明显的区别,那么它俩之间有什么区别呢?这个string buffer呢,我们说它呢,是啊叫线程,哎安全的啊,那线程安全呢,就意味着呢,它的这个执行起来这个效率。啊,效率低,而我们这个build呢,是线程不安全的。嗯,它的执行效率高。诶,而我们这个string builder,我们多说一句,它呢是在JDK5.0的时候呢新增加的,那也就是说呢,如果不涉及到这个线程的安全问题啊,是个单线程的,我们呢,就选择string builder做啊,是多线程的情况下呢,我们就选择使用buffer,那保证它是线程安全的。啊,就是这样的一个情况啊,那主体上再打上他们的这个底层结构啊就可以了,那如果再深问一问,说为什么他们存储的都是这个同样的数组结构,但为什么它一个叫可变,一个叫不可变呢?哎,这呢,作为一道思考题,大家呢下来想一想。
13:08
好,这呢,就是我们说这个string啊,以及呢,String buffer string builder底层结构的变化。
我来说两句