您的位置:首页 > 职场人生

黑马程序员——17,集合,TreeSet,二叉树,泛型

2015-08-04 18:45 579 查看
------<ahref="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

黑马程序员——17,集合,TreeSet,二叉树,泛型

/*

TreeSet:可以自动对容器内部元素排序

*/

import java.util.*;
//Collection接口的体系放在Java.util包里面

class  Jihe13
{
publicstatic void main(String[] args)
{
method();
}
public   static void   method()
{
soc("下面是method------");
TreeSet  a=  new   TreeSet();
a.add("haha01");
a.add("iujha02");
a.add("Ufwqha03");
a.add("fha01");
a.add("haha02");
a.add("Fsfsda05");
a.add("hvdv05");
a.add("vadba03");
a.add("Nhna02");
a.add("tyra07");
a.add("25D");
Iterator   it= a.iterator();
while(it.hasNext()        )
{

soc(it.next());
}
/*
TreeSet的容器里面元素被打印出来都是逐位比对之后的结果,
在逐位比对时,常见的优先顺序:数字>大写字母>小写字母,
*/
}
public static   void     soc(Object obj)
{
System.out.println(obj);
}
}
/*
以上代码编译运行结果:
下面是method------
25D
Fsfsda05
Nhna02
Ufwqha03
fha01
haha01
haha02
hvdv05
iujha02
tyra07
vadba03

*/


——————分割线——————

/*

TreeSet存储自定义对象的例子:

TreeSet的元素一定要有比较性,而且TreeSet可以自动把具有比较性的元素排序

这也是底层调用的一种表现形式TreeSet里面不可以存放重复元素,重复元素将会会被删除

*/

import java.util.*;
//Collection接口的体系放在Java.util包里面
class  Student      implements   Comparable//Comparable接口强制学生类的实例个体具备了比较性

{
private  String  name  ;
private    int   age;
Student(String  name,int age)
{
this.name=name;
this.age=age;

}
public    int   compareTo(Object  obj)
{

if( ! ( obj  instanceof  Student  ) )
{
throw new  RuntimeException("不是学生");
}
Student  a=(Student)obj;
System.out.println("这是"+this.name+"和"+a.name+"比较");
if( this.age>a.age    )
{
return 1;
}
if(this.age==a.age)
{
//主要条件相同要判断次要条件

return this.name.compareTo(a.name);
//String类也实现了Comparable接口,也有compareTo方法
//如果这里直接写return  0;的话就表示了对象是相同的
}

return  -1;
/*
TreeSet排序的原理是二叉树排序:(底层数据结构二叉树结构)
所谓的二叉树,例如:就是第一个元素进去,第二个元素进去判断若是比第一个元素大则放在右下边,(返回正数)
若是比第一个元素小则是放在左下边(返回负数)若是相同元素(返回0)则是被剔除掉。如此类推下去就会形成一个叉型树。
不过,如果元素个数过多的话,进来的元素会挑二叉树中的某一个元素做比较:
1,若是比那某个元素大则放在那某个元素的右下边,若是相等则是被剔除,
2,若是比那某个元素小泽放在左下边,
3,但是如果比那某个元素右下边的元素都大就跳到那某个元素的上一层继续比较,
就这样子,一步步确定自己在二叉树中的位置。
也可以利用这个原理,让compareTo方法返回值固定为正数或者负数,使得添加的元素按照添加顺序排序了(正序或者倒序)。
最后逐个输出的时候也是从最左边的开始按照二叉树顺序输出。
*/

}
public   String   getName()
{
return  name;
}
public   int   getAge()
{
return  age;
}

}
class  Jihe14
{
publicstatic void main(String[] args)
{
TreeSet   a=  new  TreeSet();
a.add(new   Student("haha01",12));
a.add(new  Student("haha02",19));
a.add(new   Student("haha03",26));
a.add(new   Student("haha04",15));
a.add(new  Student("haha05",1));
a.add(new   Student("haha06",16));
a.add(new   Student("haha07",76));
a.add(new   Student("haha08",17));
a.add(new  Student("haha09",17));
a.add(new   Student("haha06",16));
//TreeSet与一个Comparable接口相关,该接口强制对实现它的每一个类的对象排序
/*Comparable接口之所以有这种强制排序能力,因为该接口有一个用来比较的compareTo方法。
所以这对于TreeSet存储自定义对象时候就可以利用实现Comparable接口,并且复
写compareTo方法
*/
Iterator   it= a.iterator();
while(it.hasNext()        )
{
Student  stu=(Student)it.next()    ;
soc("名字---"+stu.getName()+"---年龄---"+stu.getAge());
}
}

public   static  void  soc(Object  obj)
{
System.out.println(obj);
}
}

/*
以上代码编译运行结果:
这是haha01和haha01比较
这是haha02和haha01比较
这是haha03和haha01比较
这是haha03和haha02比较
这是haha04和haha02比较
这是haha04和haha01比较
这是haha05和haha02比较
这是haha05和haha01比较
这是haha06和haha02比较
这是haha06和haha01比较
这是haha06和haha04比较
这是haha07和haha02比较
这是haha07和haha03比较
这是haha08和haha02比较
这是haha08和haha01比较
这是haha08和haha04比较
这是haha08和haha06比较
这是haha09和haha02比较
这是haha09和haha01比较
这是haha09和haha06比较
这是haha09和haha08比较
这是haha06和haha06比较
名字---haha05---年龄---1
名字---haha01---年龄---12
名字---haha04---年龄---15
名字---haha06---年龄---16
名字---haha08---年龄---17
名字---haha09---年龄---17
名字---haha02---年龄---19
名字---haha03---年龄---26
名字---haha07---年龄---76

*/


——————分割线——————

/*

但是如果元素自己没有或者自己本身具备的比较性不适合:

例如:

学生个体已经具备年龄的比较性,但是排序的时候需要按照名字排序,

这个时候就需要定义一个类实现Comparator接口,覆盖compare方法,该类一个比较器类,

该类的实例就是一个比较器。

把比较器放入TreeSet构造函数中,就会优先用比较器进行元素排列(不管元素本身是否具备比较性)

*/

import java.util.*;
//Collection接口的体系放在Java.util包里面
class  Student      implements   Comparable//Comparable接口强制学生类的实例个体具备了比较性

{
private  String  name  ;
private    int   age;
Student(String  name,int age)
{
this.name=name;
this.age=age;

}
public    int   compareTo(Object  obj)
{

if( ! ( obj  instanceof  Student  ) )
{
throw new  RuntimeException("不是学生");
}
Student  a=(Student)obj;
System.out.println("这是"+this.name+"和"+a.name+"比较");
if( this.age>a.age    )
{
return 1;
}
if(this.age==a.age)
{
//主要条件相同要判断次要条件

return this.name.compareTo(a.name);
}

return  -1;

}
public   String   getName()
{
return  name;
}
public   int   getAge()
{
return   age;
}

}
class  Jihe15
{
publicstatic void main(String[] args)
{
TreeSet   a=  new  TreeSet(new   Bijiao()   );//把比较器放进TreeSet构造函数中
a.add(new   Student("vdsfb1",12));
a.add(new  Student("惹我02",19));
a.add(new   Student("吧03",26));
a.add(new   Student("haha04",15));
a.add(new  Student("qwqwe5",1));
a.add(new   Student("ahs6",16));
a.add(new   Student("ibbf07",76));
a.add(new   Student("cuhn8",17));
a.add(new  Student("kvjakn09",17));
a.add(new   Student("kvjakn09",16));

Iterator   it= a.iterator();
while(it.hasNext()        )
{
Student  stu=(Student)it.next()    ;
soc("名字---"+stu.getName()+"---年龄---"+stu.getAge());
}
}

public   static  void  soc(Object  obj)
{
System.out.println(obj);
}
}
class   Bijiao   implements   Comparator
{
public  int   compare(Object  a,Object b)
{
Student   na=(Student)a;
Student  nb=(Student)b;
int  num=na.getName().compareTo(nb.getName());
//这里的compareTo方法是字符串本身就具备的方法,按照字典排列字符串
if(num==0)
{
return  na.compareTo(nb);   //按照元素本身具备的比较性进行比较
}
return  num;
}
}
/*
以上代码编译运行结果:
这是vdsfb1和vdsfb1比较
这是kvjakn09和kvjakn09比较
名字---ahs6---年龄---16
名字---cuhn8---年龄---17
名字---haha04---年龄---15
名字---ibbf07---年龄---76
名字---kvjakn09---年龄---16
名字---kvjakn09---年龄---17
名字---qwqwe5---年龄---1
名字---vdsfb1---年龄---12
名字---吧03---年龄---26
名字---惹我02---年龄---19

*/


——————分割线——————

/*

比较字符串长度

字符串本身具备了比较性,但是不合适

就用比较器了

*/

import  java.util.*;
class  Jihe16
{
publicstatic void main(String[] args)
{
TreeSet   a=new TreeSet(new  Cdbijiao());
a.add("cyufihjv");
a.add("dzsrzx");
a.add("ihu");
a.add("erasdf");
a.add("vyivlbjkbui");
a.add("tydfy");
a.add("pjokn");
a.add("cryxtsbrnr");

Iterator   it=a.iterator();
while(it.hasNext())
{
soc(it.next());
}

System.out.println("HelloWorld!");
}
public  static   void   soc(Object  obj)
{
System.out.println(obj);

}

}
class Cdbijiao   implements   Comparator
{
public  int  compare(Object  a,Object b)
{
String na=(String)a;
String  nb=(String)b;
if(na.length()==nb.length())
return   na.compareTo(nb);

if(na.length()>nb.length())
{
return  1;
}

return  -1;
}

}
/*
以上代码编译运行结果:
ihu
pjokn
tydfy
dzsrzx
erasdf
cyufihjv
cryxtsbrnr
vyivlbjkbui
Hello World!

*/


——————分割线——————

/*

关于泛型的介绍:

*/

import java.util.*;
//Collection接口的体系放在Java.util包里面
class  Student

{
private  String  name  ;
private    int   age;
Student(String  name,int age)
{
this.name=name;
this.age=age;

}

public   String   getName()
{
return   name;
}
public   int   getAge()
{
return  age;
}

}
class  Jihe17
{
publicstatic void main(String[] args)
{
ArrayList<Student>   a=  new  ArrayList<Student>();
/*
这里的<>就是一种泛型的应用,一种保护机制。
这里的例子表示的就是ArrayList类型的容器中只能够装Student类型的元素
这样使用泛型这种保护机制后之前编译会出现的两行注意提示也没有了。
但是,如果此时往容器a里面添加的不是Student类型的元素的时编译就会出问题
*/
a.add(new   Student("haha01",12));
a.add(new  Student("haha02",19));
a.add(new   Student("haha03",26));
a.add(new   Student("haha04",15));
a.add(new  Student("haha05",1));
a.add(new   Student("haha06",16));
a.add(new   Student("haha07",76));
a.add(new   Student("haha08",17));
a.add(new  Student("haha09",17));
a.add(new   Student("haha06",16));
// a.add("haha06");//这句话编译会出问题

Iterator<Student>   it= a.iterator();
/*
表示返回迭代器里面的也是Student类型的元素,
那么到时候迭代器调用next方法时返回的就不是Object类型的元素,
而是Student类型的元素了。
*/
while(it.hasNext()        )
{
//Student  stu=(Student)it.next()    ;
Student  stu=it.next()    ;
//这里就省去了类型转换的麻烦
soc("名字---"+stu.getName()+"---年龄---"+stu.getAge());
}
}

public   static  void  soc(Object  obj)
{
System.out.println(obj);
}
}
/*
以上代码编译运行结果:
名字---haha01---年龄---12
名字---haha02---年龄---19
名字---haha03---年龄---26
名字---haha04---年龄---15
名字---haha05---年龄---1
名字---haha06---年龄---16
名字---haha07---年龄---76
名字---haha08---年龄---17
名字---haha09---年龄---17
名字---haha06---年龄---16

*/


——————分割线——————

/*

关于泛型的一些知识点以及更多的关系应用:

加了<>实际上就是限制了只能够接收<>内部所表示的类型的参数

*/

import java.util.*;
//Collection接口的体系放在Java.util包里面
class  Student      implements   Comparable//Comparable接口强制学生类的实例个体具备了比较性

{
private  String  name  ;
private    int   age;
Student(String  name,int age)
{
this.name=name;
this.age=age;

}
public    int   compareTo(Object  obj)
{

if( ! ( obj  instanceof  Student  ) )
{
throw new  RuntimeException("不是学生");
}
Student  a=(Student)obj;
System.out.println("这是"+this.name+"和"+a.name+"比较");
if( this.age>a.age    )
{
return 1;
}
if(this.age==a.age)
{
//主要条件相同要判断次要条件

return this.name.compareTo(a.name);
}

return  -1;

}
public   String   getName()
{
return  name;
}
public   int   getAge()
{
return  age;
}

}
class  Jihe18
{
publicstatic void main(String[] args)
{
TreeSet<Student>   a=  new  TreeSet<Student>(new  Bijiao());//把比较器放进TreeSet构造函数中
a.add(new   Student("vdsfb1",12));
a.add(new  Student("惹我02",19));
a.add(new   Student("吧03",26));
a.add(new   Student("haha04",15));
a.add(new  Student("qwqwe5",1));
a.add(new   Student("ahs6",16));
a.add(new   Student("ibbf07",76));
a.add(new   Student("cuhn8",17));
a.add(new  Student("kvjakn09",17));
a.add(new   Student("kvjakn09",16));

Iterator<Student>   it= a.iterator();
while( it.hasNext()        )
{
Student  stu=it.next()    ;
soc("名字---"+stu.getName()+"---年龄---"+stu.getAge());
}
}

public   static  void  soc(Object  obj)
{
System.out.println(obj);
}
}
class   Bijiao   implements   Comparator<Student>
//Comparator<Student>强制指定比较器只可以比较Student类型的元素
//实际上也是Bijiao类实现了只能够接收Student类型参数的Comparator接口

{
public  int   compare(Student  a,Student b)
{
//Student   na=(Student)a;
//Student  nb=(Student)b;
//以上两句话就可以省略了
int  num=a.getName().compareTo(b.getName());
//这里的compareTo方法是字符串本身就具备的方法,按照字典排列字符串
if(num==0)
{
// return  a.compareTo(b);   //按照元素本身具备的比较性进行比较
return new Integer(a.getAge()).compareTo(new Integer(b.getAge()));
//Integer类里面也定义了自己的compareTo方法,比较的是数字的大小
}
return  num;
}
}
/*
以上代码编译运行结果:
名字---ahs6---年龄---16
名字---cuhn8---年龄---17
名字---haha04---年龄---15
名字---ibbf07---年龄---76
名字---kvjakn09---年龄---16
名字---kvjakn09---年龄---17
名字---qwqwe5---年龄---1
名字---vdsfb1---年龄---12
名字---吧03---年龄---26
名字---惹我02---年龄---19

*/


——————分割线——————

/*

泛型在自定义类中的使用:

*/

class  Person<TTT>//这种类也被称之为泛型类,带着泛型的类
//表示接收由调用者定义的类型的参数
{
private   TTT   a;
public  void   seta(TTT  a )
{
this.a=a;
}
public  TTT   geta()
{
return a;
}
}
class  Teacher
{

private   String   name="张三";
private  int   age=25;
public   int  getAge()
{
return  age;
}
public   String getName()
{
return name;
}
}
class  Student
{

private  String   name="李四";
private   int   age=13;
public   int  getAge()
{
return  age;
}
public   String getName()
{
return name;
}
}

class  Jihe19
{
public  static void   main(String[] args) //主函数
{
method();

}
public   static   void  method()
{
soc("下面是method----------------");
Person<Teacher>   a=new  Person<Teacher>();
//限制了接收的只能是Teacher类型的参数
a.seta(new  Teacher());
soc(a.geta().getName());

Person<Student>   b=new   Person<Student>();
//对于Person类的b来说,接收的只能够是Student类的参数
//与上面的没有冲突
b.seta(new  Student());
soc(b.geta().getName());
}
public  static    void   soc(Object  obj)
{
System.out.println(obj);
}
}
/*
以上代码编译运行结果:
下面是method----------------
张三
李四

*/


——————分割线——————

/*

泛型可以用在类上,也可以用在方法上

泛型方法的应用

*/

class  Person   //注意此时的类名后面没有加泛型!!!
{
public  <E> void     fanfa1(E  e)//这个就是泛型方法
//这里的<>内的E只在这个方法内有效

{
System.out.println("这是fanfa1的e---"+e);
}
public  <E> void     fanfa2(E  e)//这个就是泛型方法
//这里的<>内的E和fanfa1方法的E不是同一个E!!!
{
System.out.println("这是fanfa2的e---"+e);
}
}

class   Student<E>  //注意这里加了<E>
{
public    void   fanfa(E   e) //注意这里的void前面没有加<E>
//fanfa方法中的E和 Student<E>的E是一样的!!!
{
System.out.println("这是fanfa的e---"+e);
}
public  <E>void     fanfa1(E  e)//这个就是泛型方法,注意这里void前面加了<E>
//fanfa1方法中的E和 Student<E>的E是不相同的!fanfa1方法中的E只在fanfa1内部有效
{
System.out.println("这是fanfa1的e---"+e);
}
public  <Q> void     fanfa2(Q  q)//这个就是泛型方法
//这里的Q与Studnet<E>中的E是不一样的
{
System.out.println("这是fanfa2的q---"+q);
}

/*
public  static  void    fanfa3(E   e)
这里的E与Studnet<E>中的E是一样的,由于这里是静态方法,
在对象建立之前就存在的,但是调用该方法需要建立对象时E对应的明确类型,
所以这种写法编译出问题。为了解决这个问题,可以把泛型就定义在方法上
*/
public  static  <R>void     fanfa3(R r)
//这种写法才是正确的,而且泛型要放在返回值类型前!
//public <R> static  void     fanfa3(R r)//这种写法是错误的
{
System.out.println("这是fanfa3的r---"+r);
}
}
class  Jihe20
{
public  static void  main(String[] args)
{
method();
method2();

}
public   static  void  method()
{
soc("下面是menthod------");
Person   per=new  Person();
per.fanfa1(new  Integer(25));
per.fanfa1(62);
per.fanfa1("hushu");
per.fanfa2(new  Integer(25));
per.fanfa2(62);
per.fanfa2("hushu");
soc("HelloWorld!");
}
public  static void  method2()
{
soc("下面是menthod2------");
Student<String>   stu=new Student<String>();

stu.fanfa("hfabf");//fanfa方法只能够接收String类型的参数
//stu.fanfa(45);//这句话编译出问题
//stu.fanfa(new  Integer(25));//这句话编译出问题

stu.fanfa1("hfabf");
stu.fanfa1(45);//这句话也是可以编译运行成功的
stu.fanfa1(new Integer(25));

stu.fanfa2(78);//这句话也是可以编译运行成功的
stu.fanfa2("rtct");
stu.fanfa3("hfabf");//这句话也是可以编译运行成功的

}
public  static    void   soc(Object  obj)
{
System.out.println(obj);
}
}
/*
以上代码编译运行结果:
下面是menthod------
这是fanfa1的e---25
这是fanfa1的e---62
这是fanfa1的e---hushu
这是fanfa2的e---25
这是fanfa2的e---62
这是fanfa2的e---hushu
Hello World!
下面是menthod2------
这是fanfa的e---hfabf
这是fanfa1的e---hfabf
这是fanfa1的e---45
这是fanfa1的e---25
这是fanfa2的q---78
这是fanfa2的q---rtct
这是fanfa3的r---hfabf

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: