00:00
那接下来啊,咱们看一下叫多条件分支的跳转,多条件分支上面呢,我们实际上就是只有两个分支,说呢,你是谁等于谁啊,谁不等于谁啊,这就是二选一的这种场景,那针对多条件分支呢,典型代表就是我们说的这个叫Switch case结构,对吧?那在咱们这个自己码齿令方面呢,就增加了对Switch case结构的一个,这个设计主要呢,提到有两个自解码指令,一个呢叫做table Switch,一个呢叫lookup Switch。这两个呢,其实是比较接近的,但是也有主要的区别,那区别呢,你看我们在这个表格里边写的比较清楚,就是这个case值连续不连续的问题。那实际上我们说这个case连续也好,不连续也好都行,对吧,那关键就是连续的话呢,我们table Switch的效率会更高一些,那你要不连续的话呢,那就一个一个找这个lookup Switch呢,效率会低一些。这个能能大家理解吧,就是我们的case呢,你不是对应了几种情况嘛,那通常我们都是一些具体的整形数据,对吧,通常都是整形数据了,当然我们也有这个美女类和这个租号类型,这是后来新加的对吧,那以前的话呢,都是我们说的这个整型了,那比如说你这个case是1234这四种情况,显然呢,这四个数呢是连续的,那这种要连续的话呢,我们就用这个table Switch。
01:15
那这个时候我们就直接定位到,比如说你这个先判断是一不是一,这个起始的位置,你要知道之后呢,我们要不是一了,你那个值假设给的是三,我就直接呢定位到这儿了,就直接就蹦到三这块了,就是不用呢去顺序遍历,直接定位到你需要的那个case那个位置,而我们这个lookup Switch呢,比如说你这是一三七九二十一看呢,这就不连续,不连续的话呢,比如我们这块我写了个七,你判断一下一不是,那你就没办法根据连续的它这个间隔一样的这种场景呢,你去找到题了,那就得一个一个的这样去判断,那你这样判断的话呢,显然这个效率呢就低一些,对吧。比如我们这块要找的是20,那就意味着你得一个一个的经历,然后最终呢找到20。得是这个样子的,而且我们这块呢,如果你要找的,比如我们再往下顺也是顺到20的,我现在找的是,呃,这个我要也要找20,那一看第一个是一,那因为你是连续的,那我就不用再去找234了,我就直接一下子定位到20了,那显然呢,这个连续的场景,它的效率呢是比较高的,那这俩的区别呢,也就在这儿,所以呢,这个事儿呢,我就给大家说完了。
02:23
哎,给大家就说完了行,那下边的话呢,咱们来看一下具体的这个例子,你看我这写的这个例子这呢有一个select,那根据用户填的这个select的这个值,我们给这个内部的一个局部变量的number进行一个赋值,到底负的是具体哪个数,取决一下你这个select的这个选择,那咱们编译一下。这块我们做一个刷新过来,首先看一下这个Switch这种情况,那好,这一打开之后的话呢,我们整个结构呢,看它一会儿我们看到那个lookup Switch的时候,你会发现它的结构要稍微简洁一些,我们这里边儿这个呃,针对的就是从一开始是不是就到三呀,所以这个就one two three one two,注意这个two不是咱们说的这个图了哈,是一到三的意思,那一到三这三种情况,然后呢,我们第一个位置就是你这个一,这个一的情况下呢。
03:16
呃,如果这个要满足的话,假设咱们这个select的这个L的一,这个一呢,不就是它的这个值吗?把这个值呢,假设咱们写的是一个,诶注意这块稍微有个小细节,我先把这个呢先打开。先打开咱们再说。好了,然后这块我刷新一下,好,这个我们先说这个场景啊,这个如果我们这个select呢,假设我传入的是个二,注意我传入是个二,那咱们I6的一的话,就是索引为一,把这个二呢,就压入到我们这个操作数站里了,这呢咱们刚才分析过了,那先看一下你是不是一呢,不是一对吧,不是一的话呢,它因为你是连续的,它就直接呢就蹦到这个,当然这个二恰好是就是就是它了,你要是三的话呢,就直接蹦到三了,就略过这个二了,然后呢,后边这个事儿就直接呢做一个跳转,你是跳转到28呀,34还是40啊,乃至于说呢都不是,那就选DEFAULT46啊,这也是一个直接跳转的意思,咱们如果你输入的是二,那就跳转到这个34 34就找这儿了,那我就把这个20呢,就是压入到我们这个操作数站当中。
04:20
那保存在我们这个变量这个所以为二的这个位置放到这儿,这个所以为二的位置呢,不就是我们上边这个number这个变量吗。相当于我们给这个number呢,赋值就是20,那从我们代码层面看,也确实是就20对吧,那我们执行完这个到二之后呢,GOTO49 49直接呢就return结束了。这不就没问题吗?那如果呢,我们这个输入的是一个一呢,看一下如果我们输入的二是一的话呢,是不是就28呀,28就到这儿,那我们就复是一个十进去,就不是20了,就十进去了,十进去之后呢,然后把十保存在我们这个到一下二的一个位置,然后接下来又又构图49,这不就也结束了吗。到这儿是吧。
05:00
啊,非常的清楚,行,那刚才呢,我这块呢,是把这个break去掉了,这个呢是想给大家说明,在咱们讲语法的时候提过,如果我们这个select选的是二的话呢,这个二进来之后付了一个20,没有break,是不是接着就往下走了。接着往下走呢,我们这个number就复制为一个30了,对吧,就成这个意思了,好,那这块我们说看看这个情况,在自检码这块呢,是怎么呈现的,我们这再做一个re compile。哎,这块我们刷新一下啊,有一些变化,行,那我们这块呢,输入的是个二,那直接呢,就从这儿到34 34就到这儿了,我们把这个20呢就加入进来。二进来,然后呢,S到二存储在我们这个,所以为二的这其实就是我们的number这个20呢,就付过来了,也就是说呢,我们这20呢,一定会付,一定会付,付完之后你注意下边没有got to。那接下来呢,就往下走呗,那20操作完以后呢,又压入了一个30 30紧接着又一个s two,那把30呢,是不是就呃覆盖了原有的这个20了。
06:00
就没有了是吧,然后再GOTO46,那在这return,那最终结果呢,如果你下边去输出number,这不就是30了吗。那通过代码层面,我们原来讲过就直接往下走,那自解码指令这块呢,主要区别就是我们没有got to了,所以呢就不会发生这个叫无条件跳转,这个got to呢,也是咱们下个要讲的叫无条件跳转的一个指令,那提前呢,咱们这块呢,也反复的见了好几次了,这个大家能理解这个got to的意思,它呢也是一个无符号这个跳转的指令就跟具体类型没关系啊这样个场景。好比较清楚,然后下边呢,咱们再举一个就是lookup Switch,毕竟这块呢,它是一个连续操作,所以就是从几到几这样简写的,你看我们下边这个SWITCH2这块。所以是二这块,当然你发现我们这时候呢,我写的这些值呢,是不是就不连续了,不连续对吧?嗯,我们把这个呢,咱们刚才其实已经重新的编译过了。然后这块呢,再刷新,那还是它,那这个大家呢,你会发现呢,这块就不一样了,对吧,不是说从几到几了,那它呢,就会把这几个值都列出来,有一个小细节大家有发现没有。
07:09
你看我们这边写的时候呢,是100,我刻意的500完了放200,就是不是一个严格的从小到大的顺序。那我们这个呢,磁解码指令帮我们翻译的时候呢,大家会发现,你看它是不是严格按照从小到大的顺序来的呀,那这呢,就是对应我们这里边儿一个说明。啊,Lookup Switch,它是处理这种离散的case值,因为出于这个对效率的考虑啊,它呢会按照这个case的值的大小进行一个排序。进行个排序,然后我们就依次呢再去找就可以了,如果都没有,那就定位这个default啊是这么个小细节,大家稍微注意一下,那相当于在这个生成资金码文件的这个时候呢,就帮我们已经把这个优化的这个事儿呢,就提高了,那你再去解释运行的时候呢,这个效率稍微的要提升那么一点点啊就是这个意思。好,那我们这里边呢,假设你写的是一个这个这个200吧,是吧,假设咱传入这个200,那这个200进来之后呢,跟第一个呢去比不满足,跟第二个比满足了,注意咱们是自解码角度,这个200,那实际上呢,就是比完它以后呢,其实从代码上来看是它完之后其实没有比它,接着比的是它。
08:18
接着比的是它,但是咱们的真正解释运行都是参照自解码文件了,就不看,就没有你这个这个Java语言的这个源代码了,对吧,主要看这了,那在这儿呢,我们说就是第二个,那直接呢跳转到48。48在这儿,然后把这个30呢压进来。把30呢,保存在我们这个这个局部变量表当中,索引为二三十啊,其实就是我们这索引为一,这索引为二,还是这个number吗。没问题的是吧。好他到这保存完以后呢,然后做一个goto,那直接跳转,那这里边几个break呢,咱们这块都加着呢。行,那理解这个情况,那如果你要是个default的话呢,那就是那不是一百二百或者500的时候呢,直接走default,那就直接到54,那我们这呢是输出的是这个40是吧,保存一下,然后返回啊40行这个呢就清楚了,好这个呢比较好说,然后咱们说这个Switch呢,在JDK7的时候。
09:14
咱们在这稍微写一下CDK7。新特性。这里边儿提到呢,我们说引入了。嗯,是不是说这个死缀类型啊,在这K5.0的时候,我们提到这个应用啊,这个枚举类型,那引入了这个死追类型之后,那我们这呢,会填一个字符串,那字符串的话呢,也会去往下匹配,对吧,那字符串怎么匹配呢?怎么比较字符串说谁大谁小呢?我是不是这个不能叫谁大谁小了,我们要求这个字符串是不是严格得跟他们这里边的每一个去判断得相等,是吧。那么大家回忆一下,我们怎么判断字符串相等啊?是不是用E吧。哎,我们用ES对吧,那要是用e cos的话呢,我说呀,效率可能还不一定高。
10:04
为什么呢?你看咱们刚才呢,提到了一个一百五百和200的时候呢,它会有一个优化,就是先对我们这个数呢,进行一个排序,从小到大这样排一下,那我们这要是字符串的话呢,是不是也是要是有一个这种,诶排序的这个就是我们这个大家去想这样是想咱们判断跟这里边某一个是不是相等,咱们是不是就想到那个集合里边的S了呀。Set呢,是用来去重的,它怎么保证不重复啊,咱们当时提到过啊,哈希这种具体的算法是不是一个呢,算一个哈希值,对应的一个重写的方法叫哈的方法,还有一个方法呢,就是我们说的叫equals,对吧?你看通常我们往S中添加的这个自定义类的这种数据,你所在的类呢,要重写这两个方法,我们先拿哈西值比一下,看看你俩相不相等,如果哈值都不相等,那基本上它俩肯定不是e cos的了,那哈值相等了,咱们在ES以下,这个是效率最高的。啊,那所以这里边儿呢,大家呢,看这个源码的时候呢,你会发现这里边儿也确实按照我们刚才说的这个思路来的。
11:09
大家发现没有,这里边的话呢,你看这个怎么是数不是字符串了呢,相当于在JTK7的时候引入这个string啊,它的设计是这样子的,把这个坠呢,先按照他们的这个哈西扣的方法。你看string哈希扣方法计算一下他们各自的这个哈希值,当然这个调的是你引入的这个字符串啊,那个字符串就是你行三放的这个它的这个哈希值,这个哈希值跟咱们下边这几个哈希值去匹配一下。这个哈,一直大家看也是严格的,是不是一个升序啊。对吧,严格是个生序,其实大概大家你看的话呢,你看这你应该就知道,就是像这个52的话呢,它应该对应的就是我们说这个summer了,嗯,下边这个66的,呃,说错了,52的对应的是这个spring呢,66呢应该是这个summer,然后这个下边这不还有一个叫九十四八十,这个80呢,应该是咱们说的autumn,这个94呢,应该是咱们这个winter。
12:05
应该是这样子的啊。行,这个回过来就相当于我们也没有按照你这里边春夏秋冬的顺序,而是按照春夏冬秋这个顺序来的,对吧?OK,行,那么我们先判断一下哈希值,哈希值呢,跟这里边呢,你看看这个是不是相等,那如果哈希值相等呢,其实咱们说也有可能它们俩是不一定一样的,对吧,只是恰好这个含义值一样了,怎么办呢?那咱们会看到假设你跟第一个含义值一样,是不是就跳转到52了吧,52就到这了,52的时候呢,我们就lo一下这个二。二在咱们这个问题当中lo一些,二看看咱们这个二是几啊,这里看上边了ALO1,那就是我们这个行参,然后a store啊STORE2这个呢,是保存在alo的角标一啊。啊,Store这个存储在我们这个索引为二的这个位置上。
13:00
那相当于我们把这个season把它是吧,它呢加载到咱们的这个操作数站当中,然后又把它保存在这个数1V2的一个位置上啊,然后加载进来一个就叫负一是吧?哎,它保存在我们这个是角标为。这个三的这个局部变量表的位置了,这个lo的一个二,然后再把这个我们说的这个C呢,再拿过来对吧。行,然后呢,就是相当于跟这几个匹配完之后呢,我们还要调用一下,把这个string spring,那放过来之后呢,看一下它两个是不是equals,就是真正的再去比一下他俩这个是不是真的内容是一样子的,那如果要一样啊怎么着,如果不一样怎么着,对吧,下边就有个跳转,这个细节呢,咱们就不用去多看了,那这块呢,主要呢,就涉及到了两个方法,一个呢叫哈code,一个呢叫做这个equals。OK啊,这个呢,大家稍微关注一下,那就是我们判断字串这个多个分支的时候呢,需要拿哈一扣的值去比较,然后呢,再比较一下equals,那这样呢,能够确保是否跟这里边的每某一个字符串呢是相同的啊OK,行,那这呢就我们说的这个呃叫什么呀,就多分支的多条件的一个分支的一个跳转结构。
我来说两句