00:00
那么如果说我这个吹side里面放的是一个string,放的interior能排序的话,那我自己定义的类型它能排吗?他能不能排序呢。嗯,来,我们在这再写个class,比如说tree set是不是,哎,TEST03,那么这块的话,咱们的尝试怎么着呢?我们对我们自定义的类型进行排序,对吧,对什么呢?对自定义的类型可以对对自定义的类型来说tet可以排序吗?就是我觉得这个大家可以猜一下可以排序吗?可以排序吗,各位?啊。可以排。就我们自定义的,就先看这个啊哦,上边问问题了是吧。一会儿再看啊,一会再看来刚才说到哪了,说对自定义的数数据对自定义的类型来说,吹side可以排序吗?
01:04
可以排序吗,各位?显然是不行。对吧,你看你这个字符串是按照字典顺序排的。那如果说你这一块的话,你是一个数字的话,数字,嗯,那当然可以比较大小了,那如果说我这边呢,这个随便往我吹散的集合放个东西,它都能都能排吗。我不做什么特特殊的这个指定,它都可以去排序吧,我可以测试一下是不是,哎可以测试一下,你比如说我在这写一个class,我叫什么叫person person啊里面有个in叫age。对吧,哎,那提供一个什么呀,构造方法行不行。哎,提供过的方法,然后接下来呢,哎,我这个类就写完了,写完之后接下来干啥呀,我说person PE等于new person啊这个人年龄20。32就32吧,来person呢,P2呢,怎么着,New一个person这个年龄是20。然后呢,Person呢,我再去P3的,我new一个person出来,诶这块呢,我指定30,然后再来一个我person怎么着啊哎,我再new一个person p4吧,P4这块呢,假如说new一个person,这个person呢,他年龄是25。
02:12
啊,我这样写的,那么接下来你说我准备一个tree set集合,里边放person,然后呢,接下来我在这TS,或者叫persons persons new一个什么呀,叫吹ET,那new完这个吹ET之后呢,接下来我们在这怎么着呢?我们把persons.add把这个P1放进去,P2P3P4P2对吧,P3P4都放进去,接下来我在这里变利可以吗?可以吗?For循环类型person b persons,我们输出输出什么呀,输出这个P,输出P的时候会掉to string方法呀。是不是,哎,所以我们是不是可以在这里重写图论啊,可以重写图方法吧,哎,重写图论方法啊这个方法,那么接下来呢,我们在这儿呢,重写to方法,反馈词论叫to顿呗。
03:03
那接下来直接return什么就行了,Return一个return一个,嗯,Person中括号行吧,啊,然后age等于加一个双引号加一个age行吧,啊就这个德行啊,什么意思呢?我现在呀,先把这注释掉。啊,我把这个P1输出,你看长什么样啊,来P1输出一下。来输出一下。这个to string方法呀,它重启之后就是这样,你看对吧,Person age32嘛。是不是,哎,图顺重写图论了,你在这输出它就会调你这个方法嘛,是不是行,那现在的话,我们想说的是这个程序,你思考一下会不会出问题。Person tree set new出来,New出来之后加对吧,就是创建什么呀?哎,Tree set集合,然后呢,添加元素,然后呢,加完元素之后能够自动排序吗?
04:06
能不能呢,这个不行,而且还会出问题,各位。还会出问题啊,还会出问题,添加第一个person没问题,第二个person就出问题了。就出问题了,因为添加完第一个person之后,紧接着添加第二个person的时候,他就干什么呀,进行对比呀,排序吗?它P1和P2要比比较吧,排序好,我问大家你指定排序规则了吗。就是这个person p1和P2谁大谁小,你指定这个规则了吗?对自定义的类型来说,初赛可以排序吗?以下程序中,对于person类型来说无法排序。无法排序各位啊,因为没有指定什么对象之间的什么比较规则。
05:03
谁大谁小没说明啊,对吧,谁大谁小。谁大谁小并没有说明啊。对吧,所以说你看这个程序在执行的时候就出问题了,你看啊走你看走一个。嗯。会出现一个异常,各位,这个异常是class class的exception挺有意思啊,说class叫什么呀,叫呃,叫做person cannot,对吧,不能够cast cast转换成Java language comparable。这是个什么鬼?这是个什么鬼,说你的person无法转换成comparable。出这个问题了,这个问题我觉得大家应该很在行啊。是吧?应该很很在行这个错误吧。啊。出这个问题了。啊。
06:00
以下程序运行的时候出现了这个异常,什么异常,这个异常。对吧,哎,你看。Class说这个。他。不能转成comp。Compare比较要继承一个接口吧,啊,要继承一个接口来说的非常有道理啊,我们可以看看源代码。对不对,Person这个调I的方法,是不是底层会调map即可put方法呀,所以这块呢,我们找一下这个tree map各位。Map。加va u。就是它吧,点过去这个tree map集合里边应该有一个方法叫什么叫put吧,我们调I的方法是不是就put方法放进去了。对吧,哎,放进去之后这个源代码大家看看能不能看明白。
07:00
有时候老师又要看源代码。对,又要看源代码。啊,那这个源代码大家看一下看一下啊。呃,上边这个先不用看各位。往下这块看,这是你再捋一下啊。你注意啊,注意听,集中精力听啊,这是个吹塞调I的方法,是不是调的put方法?是不是底层会掉这个tree map的put方法好,Put方法是不是K和Y轴拿过来了,放放过来了吧,因为它要排序,是不是好大,看这里有两个分支。什么呢,置。我给大家,我给大家简单说一下啊,这个东西你可能看不太懂,我也不分析太多啊,来comp的紫色的往上走,好,大家看是不是我们这个map集合里边有一个叫comp。比较器有同学老师,比较器是个啥?你先不用管,这是个比较器啊,然后紧接着你看这个构造方法,大家看你调无参数构造方法的话,是不是比较器是空。
08:08
哎,你看我这里调的构造方法是不是一个无参数构造方法,New一个tree set的时候,我调无参构造,调无参构造,这个无参构造方法呀,它呢会给这个compare比较器附一个空。当然你还有另外一种办法是创建map集合的时候,你可以给他传一个比较器,然后比较器再给他附上去,Compare,再给他附到这个实例变量上是不是?哎,有时候老师你说这个干啥。来,因为刚才看见有这么一个颜色,对吧,我们再定位过去啊叫。来点过去啊,大家看,首先这里有这个put的方法是往里边键值都往里边放嘛,这边有个if对不对,If是CPR不等于空,你看CR等于comp吧。Comp是不是就是刚才我给大家说的那个那个那个那个叫实例变量,由于我在这里调的是无参数的构造方法,所以这个是不是等于空。
09:02
如果这个等于,这个是不是等于空。这个比较器如果是等于空的,你看如果不等于空,是不是才走这个,所以现在是不是走的这个L分支。因为现在它是空啊,为什么是空啊,因为我们没有给它赋值啊,为什么没有给它赋值啊,因为我们调的是无参数误导方法,我们调无参过导方法,就没有给比较器赋值,那么这个时候比较器是空,这个就是空,这个是空的话,那就走的是L分值了,因为你不等于空才走这吗。好,那大家看走到else,分支走L分,分支走到这之后,首先第一件事,他把这个做了强制类型转换,转换成一个comparable,看见没有。是不是转换成一个可比较的这样一个接口啊,好各位,就是在563行出了问题。刚才就在这出的问题。563。嗯。MAP1291我的天,1291是定位到哪了?All。
10:01
它定位到这儿了。呃,不用看这个呗,啊,不用看这个回来他应该就是这儿的啊。Put方法我们点过去,点过去之后呢,看这个比较级是空,这个是空,不走if,走else else这边呢,首先上来第一件事儿就是拿着K强转成compable,强管成compable的目的是为了去调这个转弯之后K吗?k.compare to,另一个K看见了吗?这个t.K是什么?就是我们这个集合当中的那个K,拿着这个K和我们这个K进行比较。对吧,比较的结果有可能小于零,也有可能大于零,也有可能I等于零,大家看这个结果是不是有可能是三个呀。你看是不是原代码,来慢慢慢慢再读啊来咱们再来一次new是不是tree set,这个tree set new的时候是不是调的是无参数构造方法,无参构造调的是无参构造,无参构造中给这个属性负的值是空。
11:04
那么紧接着我们这个程序往下走I,那你I的这个方法调的是put方法,对吧,这是个接口,各位啊,你调这个put方法的话,实际上调到哈,调到这个吹map里边put方法,吹map里边的put方法呀,它键值就是往里边加的时候,首先第一个它要看比较器是不是空,如果比较器是空的话,他就不走这个了,他就走else分支了,走到这儿之后呢,他就会把这个K呢强转成comparable这个接口类型。我们这里为什么会出这个问题?大家记得还记不记得向下转型就出这个问题。Class class exam叫线下转型,强类型转换的时候就出这个问题了,由于我们现在这个K是谁,各位是不是P1P2 P3P4person类型,Person类型现在是不是根本就不是一个comparable这个类型,你在转换强制类型转换的时候,把这个person类型在这个位置,这是person啊。各位啊,这个person转成comp的时候出问题了。
12:00
那大家看啊,如果说能转的话,是不是转转成了一个comp类型之后,他去调这个compare to和另外这个K进行比比较嘛,这个K就是那个集合里面那个K。就是你这个元素要和这个K进行比较,比较之后的结果,这个结果是一个int类型,你看见没有,有可能等于零,也有可能大于零,也有可能小于零,你看见没有。比较嘛。是不是他要排序吗。是吧,他这个在这个内存图上是什么情况呢。就说呀。我们现在呀,有一个集合,集合里边呢,放了一个对象,两个对象,三个对象,四个对象,明白吗?哎,放了很多对象,然后呢,这个对象呢是P1,这个对象呢可能是P2,这个对象呢是P3,这个对象呢是什么呀?是P4,明白吧,然后接下来怎么着呢,你在外边有个P5。你在外边有个P5,你这个P5干什么呀?你想放进去明白什么意思吧,你想把这个P5给它放进去,你得比P5和P1比,P5再和P比,P5和P3比,P5再和四比。
13:10
明白吗?他比完之后就知道该怎么排了呀,他就知道大量顺序了呀,对吧?哎,他比完之后就排了,那P5和P1进行进行比较的时候,它掉的哪个方法,大家看这里掉了一个什么compare to方法。是,这是,这就是那PP5,这就是那P1,这就是那P2,这就是那P3,这是那P4,明白吗?明白吗?你看这是个循环,这是个循环,Do while循环,循环的目的是什么?是不是拿出这个t.K一个一个比呀?对吧,然后有个左子数付给T,然后右子数又付给T,就是个T在不断的变化,那T里边是不是有K呀,有的老师左子数右子数是个什么玩意儿,这是个二叉树啊,一会我会讲讲二叉树的这个数据结构。那么这块呢,它总之啊,通过这个compare to,我拿到这个元素和这个元素之后进行比较,那就相当于说在图里面拿到这个元素,拿到这个元素和这个元素进行比较,对吧,然后再次循环,循环的时候拿到这个元素和这个元素比较。
14:06
啊,它比较之后呢,它有一个什么呀,有一个结果,这个结果有可能小于零,也有可能等于零,也有可能大于零。对不对?那现在我问大家一个问题,如果是十减去五等于,我问大家是不是大于零。那是不是代表十大于五啊?各位,这个推理没毛病吧?好,大家思考一下,十减五等于五,这个结果是大于零的。那如果说是十减去十,最后结果等于零呢?等于这个零,那就说明说明是不是十等于等于十啊。是不是相等关系啊?对吧,那如果是五减去十呢,等于负五呢?负五是不是小于零啊,小于零是不是说明是五小于十啊。这是左吧,这是不是右啊?那如果是负数的话,是不是代表左小右大?如果是正数大于零的这个数的话,是不是代表左大右小?
15:00
如果最后结果是零的话,是不是左和右是相等的?大家看这个这个这个是不是有一个小于零,这也说有一个大于零,小于零代表什么。小于零,就是说他是小的,他是大的。如果是大于零,就代表它是大的,它是小的,如果是L等于零的情况,就代表它和它是相等的情况,大家看K和K相等是不是Y6覆盖这行代码,我觉得大家都能看懂t.set value是value这个意思什么意思啊?就代表是不是给它覆盖了呀。可重复了呀。覆盖了呀,有同学老师,那是不是放在这个吹吹塞的集合里边,这个元素是不是不需要重写equals方法有道理,你不重写equals也是可以的。啊,因为它底层有有有这个比较有compar这个方法。明白吗?有compare比较这个方法,等于零的情况下,认为是同一个对象了,同一个对象value就覆盖了,看见了吗?Value是覆盖,把这个节点它的value设置成它这个T是个啥呢?是个parent是个什么东西?是个entry entry是个啥?
16:08
En是个类,这个类里边有啥,大家看是不是K是个是这是个键吗?这是值吧,好,这是键吗?这是值啊。对吧,它底层是个什么,大家看它是个二。啊,这个节点有左左侧节点,右侧节点以及节点。雨桐老师,这是什么东西,啥意思?就二塔树是个什么东西?就相当于假如这是个节点对吧,哎。这个节点下呢,有什么呀,有两个分支啊。对不对啊,有两分之,这是个节点。对不对,哎,这是个节点,但是别忘了这个上面节点还有节点,这个节点呢,它有个分支吧。对不对啊,它是不是有分支啊。哎,有分支啊,这就是二叉数。然后假如说我们这个东西就是一个T,就是那个节点。
17:09
T节点各位啊,这是T节点,那这个T节点里边有什么?大家还记不记得里面有什么东西啊?有K吧?有value。是不是,哎,还有left吧,是不是还有谁啊,Right吧。是不是还有什么呀吧。哎,你看它有五个属性,123455个属性,我们看原代表这不五个属性嘛,123455个属性,那任何一个节点它都有什么呀,在二塔树当中啊,它任何一个节点它都有什么呀,左节点这个节点现在左节点其实就是它。左节点指向的就是它,右节点指向的其实就是它。就是这个节点的内这个下,左边节点内存地址付给left,右边这个节点内存地址付给right,然后这个节点里面存这个key和value吗?是不是,然后这个parent是谁?Parent指向他。指向它,所以这个节点呢,通过它可以找到,左可以找到,右也可以找到他的父亲都可以找到,这个节点上有五个属性,有五个属性简单现在现在看看,你看这不五个属性吗?是不是,哎,那么这块的话,它。
18:12
刚才的方法是什么呢?是方法。点过去对吧,你看他怎么做的。啊。你看它比较完之后,如果小于零,小于零是负数吧。不是这啊,往下看比完之后是不是小于零,小完小于零之后,小于零是什么意思,它小吧。他说,大呀。然后它小的情况下,它就往哪找啊,往左子数上找。你看T点。T。就这个T变了,就往这儿走了。如果再把比较完之后呢,你还还是小于零的情况下,那它就还会继续把这个节点的左节点。
19:01
是是不是,是不是继续往下往左子树上走了。你看这不T吗?对吧,好,咱们先不要搞这么复杂,各位啊,总之这个地方它为什么会出错。理解了吗?来,走一个。他为什么会出错?它出错的原因是什么?各位,它出错的原因是因为我们这个类型没有实现那个接口。对吧,没有实现这个接口,你在这儿做强制类型转换呀。能转吗?转不了。转不了各位转不了。那有同就说老师,那为什么我们之前往里边放这个integer和string都可以呢,大家看啊,有没有实现这个接口。已经实现了comparable接口啊。
20:02
对吧,来再看看这个in,如果你里边放的是这个in teacher这种类型,我们点过去看一下。它是不是也实现了一个接口叫comp啊。对吧?哎,实现了comparable接口啊,你现在放到你这个吹set集合里面的东西person,你得实现那个接口才行。听懂了吗?得实现那个接口才可以。啊,实现这个接口。出现这个异常的原因是?类没有实现什么呀,java.compar接口。
我来说两句