TreeSet集合中的自定义排序:
/*
|---TreeSet:可以对集合中的元素进行排序(自然顺序)
自定义学生类,并向TreeSet集合中添加元素,自定义排序按照学生年龄。
若需要对指定元素进行排序,则需要:
1.实现comparable:此接口强行对实现它的每个类的对象进行整体排序。
这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
2.重写compareTo方法。
3.在compareTo方法中比较需要排序的元素,若本对象>要比较的对象则返回大于0的数,相等返回0,小于返回负数
注意:
排序时,当主要条件相同时,比较次要条件。
*/
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
//若不重写compareTo方法,下方的数据是不能添加的,因TreeSet中没有关于对象的比较。TreeSet不知道按照何种顺序存放对象。
ts.add(new Student("cs001",21));
ts.add(new Student("cs004",24));
ts.add(new Student("cs003",23));
ts.add(new Student("cs002",22));
ts.add(new Student("cs005",22));
ts.add(new Student("cs004",22));
Iterator it=ts.iterator();
while(it.hasNext()){
//若想要使用Student对象中的方法,需将TreeSet中的元素强制转化为Student类型。
Student st=(Student)it.next();
sop(st.getName()+"......"+st.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
//继承自comparable的实现。
class Student implements Comparable
{
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;
}
//重写coparable中的compareTo方法。
public int compareTo(Object obj){
//先判断是否为student类,否则不用比较。
if(!(obj instanceof Student))
//抛出运行时错误。
throw new RuntimeException("不是学生对象。");
//为使用Student中的方法,需将参数obj转化为Student类型。
Student s=(Student)obj;
//比较排序的元素。
if(this.age>s.age){
return 1;
}
//返回0表明为同一个对象。
//倘若年龄相同,再判断姓名是否相同,如果姓名也相同,则为同一个人(即同一个对象。)。
if(this.age==s.age){
//主要条件相同比较次要条件。
//String类型也继承自Comparable,String方法中已经复写了comparreTo(),直接使用。
return (this.getName()).compareTo(s.getName());
}
else{
return -1;
}
}
}
具有比较性的容器
/*
当元素自身不具有比较性时,或者具备的比较性不是所需要的,这时需要让容器自身具有比较性。
定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
*/
import java.util.*;
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new MyCompare());
ts.add(new Student("java 001",21));
ts.add(new Student("java 003",23));
ts.add(new Student("java 002",22));
ts.add(new Student("java 002",29));
ts.add(new Student("java 008",22));
ts.add(new Student("java 003",38));
ts.add(new Student("java 006",26));
Iterator it=ts.iterator();
while(it.hasNext()){
Student p=(Student)it.next();
sop(p.getName()+"..."+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
//继承自comparable的实现。
class Student implements Comparable
{
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;
}
//重写coparable中的compareTo方法。
public int compareTo(Object obj){
//先判断是否为student类,否则不用比较。
if(!(obj instanceof Student))
//抛出运行时错误。
throw new RuntimeException("不是学生对象。");
//为使用Student中的方法,需将参数obj转化为Student类型。
Student s=(Student)obj;
//比较排序的元素。
if(this.age>s.age){
return 1;
}
//返回0表明为同一个对象。
//倘若年龄相同,再判断姓名是否相同,如果姓名也相同,则为同一个人(即同一个对象。)。
if(this.age==s.age){
//主要条件相同比较次要条件。
//String类型也继承自Comparable,String方法中已经复写了comparreTo(),直接使用。
return (this.getName()).compareTo(s.getName());
}
else{
return -1;
}
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2){
Student p1=(Student)o1;
Student p2=(Student)o2;
int result= (p1.getName()).compareTo(p2.getName());
if(result==0){
result=(new Integer(p1.getAge())).compareTo(new Integer(p2.getAge()));
}
return result;
}
}
比较器比较字符串长度实例
/*
使用比较器实现按照字符串的长度进行排序。
*/
import java.util.*;
class TreeDemo
{
public static void main(String[] args)
{
//构建TreeSet对象。
TreeSet ts=new TreeSet(new StringLengthComparator()); //导入比较器对象参数。
//向集合中添加数据。
ts.add("java");
ts.add("jww222a");
ts.add("aweweeva");
ts.add("jawewa");
ts.add("jawewewa");
ts.add("jaa");
//创建迭代器。
Iterator it=ts.iterator();
//输出元素。
while(it.hasNext()){
System.out.println(it.next());
}
}
}
//超级方便的比较器
class StringLengthComparator implements Comparator
{
public int compare(Object ob1,Object ob2){
//强制类型转换,以便使用比较方法。
String o1=(String)ob1;
String o2=(String)ob2;
int result=(new Integer(o1.length()).compareTo(new Integer(o2.length())));
//当主要比较参数相同时,比较次要参数。
if(result==0){
return o1.compareTo(o2);
}
return result;
}
}
泛型初步引入
/*
泛型:jdk1.5版本后出现的新特性,用于解决安全问题,是一个安全机制。
优点:
1.将运行时出现的“类型转换异常”,转移到了编译时期。方便程序员解决问题,使运行时问题减少。
2.避免了强制转换的麻烦。
泛型格式:
<数据类型>
其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型做为参数传递到<>中即可。
什么时候使用泛型?
通常在集合框架中比较常见。
*/
import java.util.*;
class GenerationDemo
{
public static void main(String[] args)
{
//若直接存入其它类型,在编译时直接报错。
//在容器中指定存储的类型。
ArrayList<String> al=new ArrayList<String>();
al.add("hello");
al.add("this");
al.add("world");
al.add("!");
//数据存入迭代器时,指定存储的类型。
Iterator<String> it=al.iterator();
while(it.hasNext()){
//数据取出时,可以直接使用指定的类型取出,无需强制转换。
System.out.println(it.next());
}
}
}
按照字符串长度输出字符串(使用泛型)
/*
按照字符串长度排序(比较器),在此过程中使用泛型。
若不使用泛型,则在编译时会弹出类似“存储数据不定的安全提示”
*/
import java.util.*;
class StringLengthGeneration
{
public static void main(String[] args)
{
//设置容器中存放的是String类型。
TreeSet<String> ts=new TreeSet<String>(new myComparation());
ts.add("wweh");
ts.add("whwew");
ts.add("whas");
ts.add("wweh");
ts.add("wh");
//由于容器总存放的是String,则迭代器从容器中取出的数据也应是String。
Iterator<String> it=ts.iterator();
while(it.hasNext()){
//此处it.next()无需转化为Stirng再输出,可以直接输出。
System.out.println(it.next());
}
}
}
class myComparation implements Comparator<String> //此处使用泛型,表明要比较的类型为String
{
public int compare(String s1,String s2){ //由于在上方的比较器中已经声明了存储的类型为String,此处无需强转。
//先比较字符串长度。
int compareResult=(new Integer(s1.length())).compareTo(new Integer(s2.length()));
//若字符串长度相同,则按照自然顺序列出。
if(compareResult==0){
return s1.compareTo(s2);
}
return compareResult;
}
}
泛型类
/*
泛型类
什么时候定义泛型类?
当要操作的引用数据类型不确定时,
*/
import java.util.*;
class GenerationClass
{
public static void main(String[] args)
{
//指定Tools中存储的数据类型。
Tools<Student> ts=new Tools<Student>();
//通过该泛型类中的方法添加指定类型对象,其它类型对象不能添加。
ts.setObject(new Student());
Student sd=ts.getObject();
}
}
class Student
{
}
class Worker
{
}
//提取Student和Worker中的共性方法,构建泛型类。
//该Tools类中的引用数据类型不确定,有可能是Student或者Worker。
class Tools<TT> //设置泛型类的引用数据参数类型(自定义)。
{
private TT t;
public void setObject(TT t){
this.t=t;
}
public TT getObject(){
return t;
}
}
泛型方法
/*
泛型类定义的泛型,在整个类中有效,如果被方法调用,那么泛型类的对象明确要操作的具体类型后,
所有类中的所有方法要操作的类型就已经固定,
为了让不同方法操作不同的类型,并且要操作的类型还不确定。
那么可以将泛型定义在方法上。
对于静态方法,该方法不能访问类上定义的泛型。
如果静态方法要操作的数据类型不确定,可以将泛型定义在方法上。
*/
import java.util.*;
class GenerationFunction
{
public static void main(String[] args)
{
System.out.println("Hello World!");
//定义对象时,指定了泛型的引用类型为String,那么该泛型类中的所有方法操作的数据都为String,除了自定义的泛型方法。
Demo<String> d=new Demo<String>();
//s由于show方法的类指定了要操作的类型为String,该方法也只能操作String。
d.show("hello");
//d.show(4); //提示无法将Integer转换为String。
//show_M和show_Q为自定义的泛型方法,可以操作多个不同的数据类型。
d.show_M("M hello");
d.show_M(4);
d.show_Q("Q hello");
d.show_Q(4);
}
}
class Demo<T>
{
public void show(T t){
System.out.println(t);
}
public <Q> void show_Q(Q q){
System.out.println(q);
}
public static <M> void show_M(M m){
System.out.println(m);
}
}
泛型还可以定义在接口上
Interface inter<T>