集合框架(TreeSet)
1、二叉树:为了提高比较效率,引入了二叉树这种数据结构,这种结构的特点是:存入的时候,小的放在左,大的放在右。
取出的时候,按照左、根、右的顺序取出数据,而且总是先把左枝上的都取出之后,才进行下次取。
2、例子1:
/**
TreeSet:
可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据是:compareTo方法return 0
TreeSet排序的第一种方式,让元素自身具备比较性,
元素需要实现Comparable接口,覆盖compareTo方法
注意:当排序的时候,如果主要的条件相同,一定要判断一下次要的条件
需求1:往TreeSet集合中存储自定义的对象学生,
想按照学生的年龄进行排序。
*/
import java.util.*;
class Student implements Comparable
{
private String name;
private int age;
Student(String name,intage)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写compareTo方法
public intcompareTo(Object obj)
{
if(!(objinstanceof Student))
throw newRuntimeException("数据存储异常");
Studentstu=(Student)obj;
if(this.age>stu.age)
return 1;
if(this.age==stu.age)
returnthis.name.compareTo(stu.name); //字符串有自己的comapreTo方法。
return -1;
}
}
class TreeSetDemo
{
public static voidmain(String[] args)
{
TreeSet ts= newTreeSet();
ts.add(newStudent("lili01",20));
ts.add(newStudent("lili01",20));
ts.add(newStudent("lili",21));
ts.add(newStudent("lili",20));
for(Iterator it =ts.iterator();it.hasNext();)
{
Studentstu = (Student)it.next();
System.out.println(stu.getName()+"..........."+stu.getAge());
}
}
}
集合框架(实现Comparator方式排序)
1、TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是自己所需要,这时就需要让集合自身具备比较性。
2、比较的方式就两种:一个是元素具备比较性;一个是容器具备比较性。
3、具体的怎么做呢?
思路:定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
步骤:定义一个类,实现Comparator接口,覆盖compare方法。
好处:让程序有扩展性。
4、例子:
/*
需求:
对原有的代码进行改进,让排序方式变为按照按照姓名排序
思路:
1,定义一个比较器,将比较器对象作为参数传递给TreeSet构造函数
步骤:
1,定义一个类,实现Compator接口,复写compare方法。
*/
import java.util.*;
class Student implements Comparable
{
private String name;
private int age;
Student(String name,intage)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写compareTo方法
public intcompareTo(Object obj)
{
if(!(objinstanceof Student))
throw newRuntimeException("数据存储异常");
Studentstu=(Student)obj;
if(this.age>stu.age)
return 1;
if(this.age==stu.age)
returnthis.name.compareTo(stu.name); //字符串有自己的comapreTo方法。
return -1;
}
}
class TreeSetDemo2
{
public static voidmain(String[] args)
{
TreeSet ts= newTreeSet(new MyComparator());
ts.add(newStudent("lili01",20));
ts.add(newStudent("lili01",20));
ts.add(newStudent("lili",21));
ts.add(newStudent("lili",20));
for(Iterator it =ts.iterator();it.hasNext();)
{
Studentstu = (Student)it.next();
System.out.println(stu.getName()+"..........."+stu.getAge());
}
}
}
//自定义比较器
class MyComparator implements Comparator
{
//复写compare方法
public int compare(Objectobj1,Object obj2)
{
Students1=(Student)obj1;
Students2=(Student)obj2;
intnum=s1.getName().compareTo(s2.getName());
if(num==0)
//将年龄封装为对象
return newInteger(s1.getAge()).compareTo(s2.getAge());
return num;
}
}
集合框架(TreeSet练习)
/**
需求:按照字符串长度排序
思路:
字符串有自己的排序方式,是按照自然顺序排序的,
所以采用自定义比较器的方法
*/
import java.util.*;
class TreeSetTest
{
publicstatic void main(String[] args)
{
TreeSetts = new TreeSet(new StrLenComparator());
ts.add("ddd");
ts.add("aa");
ts.add("a");
ts.add("b");
for(Iteratorit = ts.iterator(); it.hasNext();)
{
System.out.println(it.next());
}
}
}
class StrLenComparator implementsComparator
{
publicint compare(Object o1,Object o2)
{
Strings1=(String)o1;
Strings2=(String)o2;
intnum=new Integer(s1.length()).compareTo(s2.length());
if(num==0)
returns1.compareTo(s2); //判断字符串
returnnum;
}
}
集合框架(泛型概述)
1、泛型:JDK1.5版本之后出现了新的特性,用于解决安全问题,是一个类型安全机制。
2、好处:
l 将运行时出现的问题ClassCastException,转移到了编译时期
方便于程序员解决问题,让运行时的问题减少,更加的安全。
l 避免了强制转换的麻烦。
3、例子:
import java.util.*;
class Demo
{
public static voidmain(String[] args)
{
ArrayList<String>al = new ArrayList<String>(); //定义泛型
al.add("java01");
al.add("java03");
al.add("java04");
//al.add(1)//因为整数的自动装箱,相当于al.add(newIteger(1))
//在有了泛型之后,编译时会出错
for(Iterator<String>it = al.iterator();it.hasNext();)
{
//不用强转了
System.out.println(it.next());
}
}
}
集合框架(泛型使用)
1、泛型的格式:通过<>来定义要操作的引用数据类型
2、在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要见到<>就要定义泛型。
3、<>就是用来接收数据类型的。
4、注意:在自定义描述的时候,equals方法中的Object 是不能够变的。
集合框架(泛型类)
/**
泛型类:
什么时候定义泛型类呢?
当类中要操作的引用数据类型不确定的时候,
早期定义Object来完成扩展,
现在定义泛型类。
例子:
*/
class Worker
{
}
class Student
{
}
class Utils<QQ>
{
privateQQ q;
publicvoid setObject(QQ q)
{
this.q=q;
}
publicQQ getObject()
{
returnq;
}
}
class Demo3
{
publicstatic void main(String[] args)
{
Utils<Worker>u = new Utils<Worker>();
u.setObject(newWorker());
Workerw = u.getObject();
}
}
集合框架(泛型方法)
/**
1,泛型类定义的泛型,在整个类中有效。
如果被方法使用,那么泛型类的对象的对象明确要操作的具体的数据类型后
所要操作的类型就已经固定了。
2,为了让不同的方法可以操作不同的类型,而且类型还不确定
可以将泛型定义在方法上。
注意:
1。泛型定义在方法上的时候,放在修饰符的后面,返回类型的前面。
2。静态方法无法无法访问定在类上的泛型,只能定义在方法上。
*/
class Demo<T>
{
publicvoid show(T t)
{
System.out.println("和类的类型相同:"+t);
}
//定义在方法上
public<Q> void print(Q q)
{
System.out.println("泛型函数:"+q);
}
//静态
publicstatic <T> void show2(T t)
{
System.out.println("静态泛型函数:"+t);
}
}
class Demo4
{
publicstatic void main(String[] args)
{
Demo<String>d =new Demo<String>();
d.show("java01");
//d.show(3);
d.print(5);
d.show2("java01");
d.show2(4);
}
}
集合框架(泛型接口)
//泛型接口的两种体现形式
interface Inter<T>
{
publicabstract void show(T t);
}
//第一种,定义子类的时候知道类型
class InterImpl implementsInter<String>
{
publicvoid show(String s)
{
System.out.println("show:"+s);
}
}
//定义类的时候,类型仍然不确定,注意前后一致
class InImpl<T> implementsInter<T>
{
publicvoid show(T t)
{
System.out.println("show2:"+t);
}
}
class Demo5
{
publicstatic void main(String[] args)
{
InterImpli = new InterImpl();
i.show("ddd");
InImpl<Integer>ii = new InImpl<Integer>();
ii.show(4);
}
}
集合框架(泛型限定)
/**
1. ? 通配符 。也可以理解为占位符
通配符和一般的(T)的不同之处,是通配符不可以在后面操作。
2. 在集合中左右两边定义的结合的类型得是一致的。
例如:ArrayList<Person>ts = new ArrayList<Student>;
这句话编译无法通过的。
3、泛型的限定:
上限:? extendsE :可以接收E类型或者E的子类型
下限:? super E :可以接收E类型或者E的父类型
4、用处:泛型限定是用于做泛型扩展用的。
*/
import java.util.*;
class Person
{
privateString name;
Person(Stringname)
{
this.name=name;
}
publicString getName()
{
returnname;
}
}
class Student extends Person
{
Student(Stringname)
{
super(name);
}
}
class Demo6
{
/*
publicstatic void main(String[] args)
{
通配符的演示:
ArrayList<String>al = new ArrayList<String>();
al.add("java01");
al.add("java01");
al.add("java03");
al.add("java04");
ArrayList<Integer>al1 = new ArrayList<Integer>();
al1.add(1);
al1.add(2);
al1.add(3);
al1.add(4);
printColl(al);
printColl(al1);
}
publicstatic void printColl(ArrayList<?> al) //通配符的使用,因为类型不确定
{
for(Iteratorit = al.iterator(); it.hasNext();)
{
System.out.println(it.next());
}
}
*/
//泛型限定
publicstatic void main(String[] args)
{
ArrayList<Person>al = new ArrayList<Person>();
al.add(newPerson("lilil1"));
al.add(newPerson("lilil2"));
al.add(newPerson("lilil3"));
ArrayList<Student>al1 = new ArrayList<Student>();
al1.add(newStudent("lilil》》1"));
al1.add(newStudent("lilil》》2"));
al1.add(newStudent("lilil》》3"));
printColl(al);
printColl(al1);
}
publicstatic void printColl(ArrayList<? extends Person> al) //泛型限定
{
for(Iterator<?extends Person> it = al.iterator(); it.hasNext();)
{
System.out.println(it.next().getName());
}
}
}