treemapWord文档下载推荐.docx
《treemapWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《treemapWord文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
![treemapWord文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2023-2/1/678b5cd7-4251-4cc2-b446-16bf1e77a66e/678b5cd7-4251-4cc2-b446-16bf1e77a66e1.gif)
this.name=name;
this.age=age;
publicStringgetId(){
returnid;
publicvoidsetId(Stringid){
publicStringgetName(){
returnname;
publicvoidsetName(Stringname){
publicIntegergetAge(){
returnage;
publicvoidsetAge(Integerage){
@Override
publicStringtoString(){
return"
User[name="
+name+"
age="
+age+"
]"
;
publicbooleanequals(Objectobj){
returntrue;
publicinthashCode(){
return0;
publicintcompareTo(Usero){
returnthis.age>
o.getAge()?
1:
this.age==o.getAge()?
0:
-1;
}
测试代码:
publicclassTestUser{
publicstaticvoidmain(String[]args){
Map<
User,Integer>
userHashMap=newHashMap<
();
Useruser1=newUser("
1"
"
Jay"
30);
Useruser2=newUser("
2"
Jolin"
21);
Useruser3=newUser("
3"
JackCheng"
22);
Useruser4=newUser("
4"
BruceLee"
userHashMap.put(user1,100);
userHashMap.put(user2,200);
userHashMap.put(user3,300);
userHashMap.put(user4,400);
System.out.println(userHashMap);
userTreeMap=newTreeMap<
userTreeMap.put(user1,100);
userTreeMap.put(user2,200);
userTreeMap.put(user3,300);
userTreeMap.put(user4,400);
System.out.println(userTreeMap);
结果
{User[name=Jay,age=30]=400}
{User[name=Jolin,age=21]=200,User[name=JackCheng,age=22]=400,User[name=Jay,age=30]=100}
1
2
3
结论:
对于HashMap而言,只要key的equals相等就表示两个元素相等,HashMap就存不进去;
而TreeMap是不管equals和hashCode的,只要compareTo相等就表示两个元素相同,就存不进去。
2.第二次比较:
现在我们按照id来重写hashCode和equals方法,如下:
finalintprime=31;
intresult=1;
result=prime*result+((id==null)?
id.hashCode());
returnresult;
if(this==obj)
if(obj==null)
returnfalse;
if(getClass()!
=obj.getClass())
Userother=(User)obj;
if(id==null){
if(other.id!
=null)
}elseif(!
id.equals(other.id))
测试代码不变,还是上面的测试代码,结果:
{User[name=Jolin,age=21]=200,User[name=Jay,age=30]=100,User[name=BruceLee,age=22]=400,User[name=JackCheng,age=22]=300}
说明:
HashMap只要equals不等那就表示不等,而对于TreeMap如果compareTo相等,那么2个元素就相等,并且排序是按照compareTo方法定义的排序规则。
接下来再在测试代码里面添加List测试:
List<
userList=newArrayList<
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
System.out.println(userList);
Collections.sort(userList);
结果:
[User[name=Jay,age=30],User[name=Jolin,age=21],User[name=JackCheng,age=22],User[name=BruceLee,age=22]]
[User[name=Jolin,age=21],User[name=JackCheng,age=22],User[name=BruceLee,age=22],User[name=Jay,age=30]]
当调用sort方法之后List里面的元素就按照age排序了。
对于Comparator,一种叫做策略模式的设计模式,我们在User中实现Comparable接口,重写里面的方法,可以实现对User按age排序,这个排序算法是
存在于User内部的,换句话说User和排序算法是相互依存的,User只能用compareTo这个算法,而compareTo算法也只能为User服务,那么如果我们其他
地方也有同样的需求,就只能再实现一次Comparable,来为另外一个对象服务,这就有点重复的感觉,而且代码没有得到复用,样子对象和算法混在一
起耦合性很强,于是希望把算法和模型分离出来,让算法单独存在,不同的对象可以使用同一个算法,并且二者是分离的,没有混为一体。
当然可以分
开那必然还是可以放在一起的。
用一句比较专业点的话来讲就是策略模式有两个特点:
1.封装变化。
2.变成中使用接口而不实现接口。
如果我再说得直白一点,策略模式就是一种面向接口编程的思想。
这点在多线程里面也有所体现,就是为什么我们在开启新线程的时候要newThread(Runnable接口),
参数传接口而不推荐去继承Thread,虽然也可以继承,这也是体现面向对象的封装特性,将run的算法和线程分离,可以实现run所在类的复用,虽然一般都不会去复用,
当然这里还有一点就是Java只能单继承,如果继承了Thread就不能在继承其他的类。
此时我们的User是按照age排序,那如果想按照名字排序呢,那就没办法了,
但是如果将算法分离出来,需要用名字排序我们就传用名字排序的算法进去,需要用age排序就传age排序算法进去。
环境持有接口引用,通过set方法将接口实现
传入到环境,在环境中来调用接口方法,这完完全全是面向接口的特点。
下面的第一个例子就是存放在一起的,因为TreeMap的构造方法其中就有一个是待Comparator
接口参数的构造方法,该参数只要实现了Comparator接口就行,如下:
publicTreeMap(Comparator<
?
superK>
comparator){
parator=comparator;
举例:
有一个Person类,实现了Comparator接口,并且按照岁数排序:
publicclassPersonimplementsComparator<
Person>
publicPerson(){
publicPerson(Stringid,Stringname,Integerage){
Person[name="
Personother=(Person)obj;
publicintcompare(Persono1,Persono2){
returno1.getAge()>
o2.getAge()?
o1.getAge()==o2.getAge()?
测试:
publicclassTestPerson{
Person,Integer>
personHashMap=newHashMap<
Personperson1=newPerson("
Personperson2=newPerson("
Personperson3=newPerson("
Personperson4=newPerson("
personHashMap.put(person1,100);
personHashMap.put(person2,200);
personHashMap.put(person3,300);
personHashMap.put(person4,400);
System.out.println(personHashMap);
personTreeMap=newTreeMap<
(newPerson());
personTreeMap.put(person1,100);
personTreeMap.put(person2,200);
personTreeMap.put(person3,300);
personTreeMap.put(person4,400);
System.out.println(personTreeMap);
{Person[name=Jolin,age=21]=200,Person[name=Jay,age=30]=100,Person[name=BruceLee,age=22]=400,Person[name=JackCheng,age=22]=300}
{Person[name=Jolin,age=21]=200,Person[name=JackCheng,age=22]=400,Person[name=Jay,age=30]=100}
依然是compara方法相等的元素表示相同,只能存放一个进去,并且是按照age排序的。
在List中的结果:
personList=newArrayList<
personList.add(person1);
personList.add(person2);
personList.add(person3);
personList.add(person4);
System.out.println(personList);
Collections.sort(personList,newPerson());
[Person[name=Jay,age=30],Person[name=Jolin,age=21],Person[name=JackCheng,age=22],Person[name=BruceLee,age=22]]
[Person[name=Jolin,age=21],Person[name=JackCheng,age=22],Person[name=BruceLee,age=22],Person[name=Jay,age=30]]
调用sort方法前没排序,而调用之后按照age排序了。
其实将算法和模型分离也非常类似,只需要将实现Comparator接口的类单独拿出去就ok了。
现在定义Person类,不实现Comparator接口,而将SortPerson类来
实现该接口,其实就是用SortPerson类代替之前TreeMap中的参数,之前的参数是实现了Comparator接口的Person对象。
Person类:
publicclassPerson{
if(ob