黑马程序员java基础之集合Set中的TreeSet和泛型

------- android培训java培训、期待与您交流! ----------

TreeSet会将元素自动排序。往该集合中存元素或者对象,实现排序,就必须是元素或者对象具备比较性,所以对象要实现Comparable接口,具有比较性

练习:将TreeSet集合中添加对象学生,按照学生的年龄进行排序

import java.util.*;
class TreeSetDemo
{
   public static void main(String[] args)
   {
      TreeSet ts=new TreeSet();		//新建一个TreeSet集合
	//添加元素
      ts.add(new student("zhangsan",20));	
      ts.add(new student("zhangsan1",21));
      ts.add(new student("zhangsan2",22));
      ts.add(new student("zhangsan3",22));
  
      Iterator it=ts.iterator();	//引用迭代器遍历集合元素
      while(it.hasNext())
      {
         student stu=(student)it.next();	//将集合中元素强转为Student类型,便于使用Student中的方法
         System.out.println(stu.GetAge()+"----"+stu.GetName());
       }
    }
}

class student implements Comparable	//学生实现Comparable接口,继而具有比较性
{
	//引用name,age变量
  private String name;
  private int age;

  student(String name,int age)	//构造函数
  {
	//使name和age作用于整个类中
     this.name=name;
     this.age=age;
   }
  public String GetName()	//获取姓名
  {
      return name;
   }
   public int GetAge()		//获取年龄
  {
      return age;
   }
   public int compareTo(Object obj)	//覆盖Comparable中的compareTo方法,构造属于学生的比较方法
   {
      
       if(!(obj instanceof student))
       throw new RuntimeException("不是学生对象");
     
       student s=(student)obj;		//将传入对象强转为student类,
       System.out.println(this.name+"---compareto---"+s.name);
     
       if(this.age>s.age)
       return 1; 

       if(this.age==s.age)
       {
		//将姓名按照字典顺序排序
          return this.name.compareTo(s.name); 	//<span style="color:#ff0000;">字符串本身就具备比较性,实现了Comparable接口,所以可以直接进行比较</span>
        }
       return -1;
     
     // return 0;

    }
}
TreeSet底层数据结构是二叉树

保证元素唯一性的依据:compareTo方法中的  return 0,该结果视为元素相同,所以只有一个会保留

以上就是TreeSet的第一种排序方法,让元素本身具备比较性,让元素对象实现Comparable接口。即为自然顺序


TreeSet第二种排序方式:让集合自身具备比较性,让集合按照指定的比较器进行比较。将比较器对象作为参数传给TreeSet集合的构造函数

定义一个类,实现comparator,重写compare(参数1,参数2)方法

import java.util.*;
class TreeSetDemo2
{
   public static void main(String[] args)
   {
      TreeSet ts=new TreeSet(new Mycompare());
      ts.add(new Student("zhangsan",20));
      ts.add(new Student("zhangsan1",21));
      ts.add(new Student("zhangsan2",22));
      ts.add(new Student("zhangsan3",20));
      ts.add(new Student("zhangsan1",25));
  
      Iterator it=ts.iterator();	//创建迭代器,遍历集合元素
      while(it.hasNext())
      {
         Student stu=(Student)it.next();
         System.out.println(stu.getName()+"----"+stu.getAge());
       }
    }
}
class Student	//构造学生类
{
  private String name;
  private int age;
  Student(String name,int age)
  {
	//构造函数将name,age运用到整个类中
      this.name=name;
      this.age=age;
   }
  public int getAge()	//获取年龄
  {
      return age;
   }
  public String getName()	//获取姓名
  {
      return name;
   }
}

class Mycompare implements Comparator	//自定义比较器类
{
    public int compare(Object o1,Object o2)	//重写Comparator的compare方法
    {
	//将传入对象强转为学生类
        Student s1=(Student)o1;
        Student s2=(Student)o2;

       int num= (s1.getName().compareTo(s2.getName()));		//此处的campareTo是使用String中的方法
       if(num==0)
       {
  	//因为Integer对象也实现了comparator接口,具备比较性,所以使用该对象比较年龄更加简洁

       return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));	//将年龄封装成Integer对象使用比较方法

       /*
       if(s1.getAge()>s2.getAge())
       return 1;
       if(s1.getAge()==s2.getAge())
       return 0;
      
       return -1;
      */

       }
      return num;
     }
  
 }

当以上两种比较方法都存在时,以comparator比较器为主


二.泛型

           泛型用于解决安全问题,是一个安全机制

好处:将运行时期出现问题classCastException(类型转换异常),转移到了编译时期,让运行时问题减少,更加安全;避免了强制转换的麻烦

泛型的格式:通过<>来定义要操作的引用数据类型。通常在在集合框架中很常见

import java.util.*;
class GenericDemo 
{
   public static void main(String[] args)
   {
      ArrayList <String> al=new ArrayList<String>();	//创建一个集合,并且使用泛型,参数基本类型是String类型的
      //添加元素
      al.add("abcd");
      al.add("abcd987");
      al.add("abcd75");
      al.add("abcd087");

      Iterator <String> it = al.iterator();	//使用迭代器遍历元素
      while(it.hasNext())
      {
          String s=it.next();
          System.out.println(s+s.length());	//打印元素和长度
       }
   }
}
按照集合中的字符串元素按照其长度比较排序,如果长度相同,再将字符串按照字典顺序排序
import java.util.*;
class GenericDemo2
{
   public static void main(String[] args)
   {
     TreeSet <String> ts=new TreeSet<String>(new LenComparator());	//创建集合,泛型定义是String类型的,并传入比较器
   
	//添加元素
     ts.add("abcd");
     ts.add("cc");
     ts.add("aaa");
     ts.add("z");
     ts.add("hah");

     Iterator<String> it=ts.iterator();	//使用迭代器
     while(it.hasNext())
      {
         String s=it.next();		//获取集合中的元素
         System.out.println(s);
      }
    }
}

class LenComparator implements Comparator<String>	//构造长度比较器
{
    public int compare(String o1,String o2)	//重写compare方法
    {
       int num=new Integer(o1.length()).compareTo(new Integer(o2.length()));	//使用Integer对象的比较方法
    
       if(num==0)
          return o2.compareTo(o1);	//如果长度相等,再比较元素字符串本身
       return num;
    }
}

早期没有泛型时的工具类

import java.util.*;
class Tool
{
	private Object obj;
	public void setObject(Object obj)	//设置对象
	{
		this.obj=obj;	
	}
	
	public void getObject()		//获取对象
	{
		return obj;
	}
}
class GenericClass
{
	public void main(String[] args)
	{
		Tool t=new Tool();
		t.setObject(new Student());	//设置对象,传入一个Student对象
		Student s=(Student)t.getObject();	//使用强转,获取学生对象
	}
}
使用泛型类

class GenericClass
{
	public void main(String[] args)
	{
		/*
		Tool t=new Tool();
		t.setObject(new Student());	//设置对象,传入一个Student对象
		Student s=(Student)t.getObject();	//使用强转,获取学生对象
		*/
		
		Utils<worker> u=new Utils<worker>();

		u.setObject(new Student());
		worker w=u.getObject();
	}
}
class Utils<QQ>
{
	private QQ q;
	public void setObject(QQ q)	//设置对象
	{
		this.q=q;	
	}
	
	public 	QQ getObject()		//获取对象
	{
		return q;
	}
}

当类中操作的引用数据类型不确定的时候,就使用泛型来完成扩展
泛型类定义的泛型,在整个类中都有效,如果被方法使用,所要操作的类型已经被固定,为了让不同方法可以操作不同类型,将泛型就定义在了方法上

import java.util.*;
class GenericDemo4
{
	public static void main(String[] args)
	{
		Demo d=new Demo();	//创建Demo对象
		//通过将泛型定义在方法上,传入不同参数
		d.show("haha");		
		d.show(new Integer(4));
		d.print("heihei");
	}
}
class Demo
{
	public <T> void show(T t)	//将泛型定义在show方法上
	{
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q)	//将泛型定义在print方法上
	{
		System.out.println("print:"+q);
	}
}

静态方法不可以访问类上定义的泛型
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。同时在类上定义泛型,类中方法如果使用不同泛型,不影响方法的使用

import java.util.*;
class GenericDemo4
{
	public static void main(String[] args)
	{
		/*
		Demo d=new Demo();	//创建Demo对象
		//通过将泛型定义在方法上,传入不同参数
		d.show("haha");		
		d.show(new Integer(4));
		d.print("heihei");
		*/
		Demo<String> d=new Demo<String>();	//在类上定义泛型
		d.show("haha");
		d.print(4);

	}
}
class Demo<T>
{
	public <T> void show(T t)	//将泛型定义在show方法上
	{
		System.out.println("show:"+t);
	}
	public static <Q> void print(Q q)	//将泛型定义在print方法上
	{
		System.out.println("print:"+q);
	}
}


泛型定义在接口上

import java.util.*;
class GenericDemo5
{
	public static void main(String[] args)
	{
		In in=new In();
		in.show("haha");
	}
}

interface Inter<T>	//创建接口和接口的show方法
{
	void show(T t);
}

class In implements Inter<String>	//新建一个类实现Inter接口,
{
	public void show(String t)	//复写show方法
	{
		System.out.println("show:"+t);
	}
}

import java.util.*;
class GenericDemo5
{
	public static void main(String[] args)
	{
		In in=new In();		//新建类
		in.show("haha");

		Inte<Integer> inte=new Inte<Integer>();		//新建泛型为Integer的类
		inte.show(4);
	}
}

interface Inter<T>	//创建接口,泛型为String
{
	void show(T t);		//复写接口的show方法
}

class In implements Inter<String>	//新建一个类实现Inter接口,
{
	public void show(String t)	//复写show方法
	{
		System.out.println("show:"+t);
	}
}

class Inte<T> implements Inter<T>	//将泛型定义在实现接口的类上
{
	public void show(T t)	//复写show方法
	{
		System.out.println("show:"+t);
	}
}


?通配符,占位符

泛型限定   ?extends E   可以接收E类型或其子类 : 上限

   ?super E  可以接收E或其父类: 下限 

import java.util.*;
class GenericDemo3
{
  public static void main(String[] args)
  {
	/*
     ArrayList<String> al=new ArrayList<String>();	//创建一个泛型为String类型的集合
   //添加元素
     al.add("abcq");
     al.add("abcq");
     al.add("abcq");

     ArrayList<Integer> al1=new ArrayList<Integer>();	创建一个泛型为String类型的集合
  //添加元素
     al1.add(4);
     al1.add(5);
     al1.add(9);
      
     printColl(al);
     printColl(al1);
	*/

	ArrayList<Person> al=new ArrayList<Person>();	//建立泛型为Person的集合
	al.add(new Person("abd01"));
	al.add(new Person("abd02"));
	al.add(new Person("abd03"));

	printColl(al);

	ArrayList<Student> all=new ArrayList<Student>();	//建立泛型为Person的集合
	all.add(new Student("abd--1"));
	all.add(new Student("abd--2"));
	all.add(new Student("abd--3"));
	printColl(all);
	
   }

	//使用通配符“?”表示调用不明确的数据类型
   public static void printColl(ArrayList<span style="color:#ff0000;"><? extends Person</span>> al)	//将迭代器封装为一个方法,方便调用.   将泛型限定为Person和其子类
   {
        Iterator<<span style="color:#ff0000;">? extends Person</span>> it=al.iterator();	//使用迭代器,    将泛型限定为Person和其子类
        while(it.hasNext())
        {
           System.out.println(it.next().getName());
         }
    }
}


class Person	//定义Person类
{
	private String name;	//声明姓名变量
	Person(String name)
	{
		this.name=name;		//构造方法初始化姓名,将其作用于整个类中
	}
	public String getName()
	{
		return name;
	}
}

class Student extends Person	//定义学生类继承perosn类
{
	Student(String name)
	{
		super(name);	//构造函数初始化name引用父类变量
	}
}
TreeSet中的泛型限定

import java.util.*;
class GenericDemo7
{
	public static void main(String[] args)
	{
		TreeSet<Student> ts=new TreeSet<Student>(new Comp());	//创建泛型为学生的集合,将比较器传入
	
		//添加元素
		ts.add(new Student("abc-3"));
		ts.add(new Student("abc-2"));
		ts.add(new Student("abc-1"));

		Iterator<Student> it=ts.iterator();	//使用迭代器,遍历元素

		while(it.hasNext())
		{
			System.out.println(it.next().getName());
		}

		
		
		TreeSet<Worker> trs=new TreeSet<Worker>(new Comp());	//创建泛型为工人的集合,将比较器传入
	
		//添加对象
		trs.add(new Worker("wabc-3"));
		trs.add(new Worker("wabc-2"));
		trs.add(new Worker("wabc-1"));

		Iterator<Worker> ite=trs.iterator();	//引用迭代器,遍历元素

		while(ite.hasNext())
		{
			System.out.println(ite.next().getName());
		}
	}
}
class Comp implements Comparator<Person>	//将比较器泛型定义为父类型,提高复用性	
{
	public int compare(Person s1,Person s2)		//复写compare方法
	{
		return s1.getName().compareTo(s2.getName());	//使用String类的比较方法
	}
	
}

class Person	//定义Person类
{
	private String name;	//声明姓名变量
	Person(String name)
	{
		this.name=name;		//构造方法初始化姓名,将其作用于整个类中
	}
	public String getName()
	{
		return name;
	}
}

class Student extends Person	//定义学生类继承perosn类
{
	Student(String name)
	{
		super(name);	//构造函数初始化name引用父类变量
	}
}

class Worker extends Person	//定义工人类继承person类
{
	Worker(String name)
	{
		super(name);	//构造函数初始化name引用父类变量
	}
}



总结,泛型限定就是为提高程序扩展性而使用的










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值