------<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
*/