【15】集合2_TreeSet集合、泛型的应

本文详细介绍了Java集合框架中的TreeSet集合,包括其基本概念、数据结构、排序方式及泛型应用等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


7.2TreeSet  集合

 

Set:无序,不可以重复元素。

         |--HashSet:数据结构是哈希表。线程是非同步的。

                                     保证元素唯一性的原理:判断元素的hashCode值是否相同。

                                     如果相同,还会继续判断元素的equals方法,是否为true。

 

         |--TreeSet:可以对Set集合中的元素进行排序。

                                     底层数据结构是二叉树。

                                     保证元素唯一性的依据:

                                     compareTo方法return 0.

 

                                     TreeSet排序的第一种方式:让元素自身具备比较性。

                                     元素需要实现Comparable接口,覆盖compareTo方法。

                                     也种方式也成为元素的自然顺序,或者叫做默认顺序。

 

                                     TreeSet的第二种排序方式。

                                     当元素自身不具备比较性时,或者具备的比较性不是所需要的。

                                     这时就需要让集合自身具备比较性。

                                     在集合初始化时,就有了比较方式。

 

 

练习一:往TreeSet集合中存储自定义对象学生,按照学生的年龄进行排序。

 

import java.util.*;
 
/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。
 
记住,排序时,当主要条件相同时,一定判断一下次要条件。
*/
 
class TreeSetDemo
{
         public static void main(String[] args)
         {
                   TreeSet ts = new TreeSet();
 
                   ts.add(new Student("lisi02",22));
                   ts.add(new Student("lisi007",20));
                   ts.add(new Student("lisi09",19));
                   ts.add(new Student("lisi08",19));
                   //ts.add(new Student("lisi007",20));
                   //ts.add(new Student("lisi01",40));
 
                   Iterator it = ts.iterator();
                   while(it.hasNext())
                   {
                            Student stu = (Student)it.next();
                            System.out.println(stu.getName()+"..."+stu.getAge());
                   }
         }
}
 
 
class Student implements Comparable//该接口强制让学生具备比较性。
{
         private String name;
         private int age;
 
         Student(String name,int age)
         {
                   this.name= name;
                   this.age= age;
         }
 
         public int compareTo(Object obj)
         {
 
                   //return 0;
                  
                   if(!(obj instanceof Student))
                            thrownew RuntimeException("不是学生对象");
                   Student s = (Student)obj;
 
                   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);
                   }
                   return -1;
                   /**/
         }
 
         public String getName()
         {
                   return name;
 
         }
         public int getAge()
         {
                   return age;
         }
}


 

7.2.1让容器自身具备比较性

 

当元素自身不具备比较性,或者具备的比较性不是所需要的。

这时需要让容器自身具备比较性。

定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

 

当两种排序都存在时,以比较器为主。

 

定义一个类,实现Comparator接口,覆盖compare方法。

 

练习二:让容器自身具备比较性

import java.util.*;
 
class Student implements Comparable//该接口强制让学生具备比较性。
{
         private String name;
         private int age;
 
         Student(Stringname,int age)
         {
                  this.name = name;
                   this.age= age;
         }
 
         publicint compareTo(Object obj)
         {
 
                   //return0;
                  
                   if(!(obj instanceof Student))
                            throw new RuntimeException("不是学生对象");
                   Students = (Student)obj;
 
                   //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);
                   }
                   return -1;
                   /**/
         }
 
         public String getName()
         {
                   return name;
 
         }
         public int getAge()
         {
                   return age;
         }
}
class TreeSetDemo2
{
         public static void main(String[] args)
         {
                   TreeSet ts = new TreeSet();
 
                   ts.add(new Student("lisi02",22));
                   ts.add(new Student("lisi02",21));
                   ts.add(new Student("lisi007",20));
                   ts.add(new Student("lisi09",19));
                   ts.add(new Student("lisi06",18));
                   ts.add(new Student("lisi06",18));
                   ts.add(new Student("lisi007",29));
                   //ts.add(new Student("lisi007",20));
                   //ts.add(new Student("lisi01",40));
 
                   Iterator it = ts.iterator();
                   while(it.hasNext())
                   {
                            Student stu = (Student)it.next();
                            System.out.println(stu.getName()+"..."+stu.getAge());
                   }
         }
}
 
class MyCompare implements Comparator
{
         public int compare(Object o1,Object o2)
         {
                   Student s1 = (Student)o1;
                   Student s2 = (Student)o2;
 
                   int num = s1.getName().compareTo(s2.getName());
                  if(num==0)
                   {
 
                            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
                            /*
                            if(s1.getAge()>s2.getAge())
                                     return 1;
                            if(s1.getAge()==s2.getAge())
                                     return0;
                            return -1;
                            */
                   }
 
                  
                   return num;
 
         }
}


 

练习三:按照字符串长度排序。

 

/*
字符串本身具备比较性。但是它的比较方式不是所需要的。
这时就只能使用比较器。
*/
 
import java.util.*;
class TreeSetTest
{
         public static void main(String[] args)
         {
                   TreeSet ts = new TreeSet(new StrLenComparator());
 
                   ts.add("abcd");
                   ts.add("cc");
                   ts.add("cba");
                   ts.add("aaa");
                   ts.add("z");
                   ts.add("hahaha");
 
                   Iterator it = ts.iterator();
 
                   while(it.hasNext())
                   {
                            System.out.println(it.next());
                   }
         }
}
 
class StrLenComparator implementsComparator
{
         public int compare(Object o1,Object o2)
         {
                   String s1 = (String)o1;
                   String s2 = (String)o2;
 
                   /*
                   if(s1.length()>s2.length())
                            return1;
                   if(s1.length()==s2.length())
                            return0;
                            */
 
                           
 
                   int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
                   if(num==0)
                            return s1.compareTo(s2);
 
                   return num;
         }
}


 

7.2.2泛型

 

JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

 

好处

1.将运行时期出现问题ClassCastException,转移到了编译时期。,

         方便于程序员解决问题。让运行时问题减少,安全。,

 

2,避免了强制转换麻烦。

 

泛型格式:通过<>来定义要操作的引用数据类型。

 

在使用java提供的对象时,什么时候写泛型呢?

 

通常在集合框架中很常见,

只要见到<>就要定义泛型。

 

其实<> 就是用来接收类型的。

 

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 

练习四:泛型

class GenericDemo
{
         public static void main(String[] args)
         {
 
                   ArrayList<String> al = new ArrayList<String>();
 
                   al.add("abc01");
                   al.add("abc0991");
                   al.add("abc014");
 
                   //al.add(4);//al.add(newInteger(4));
                  
 
                   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());
 
                   ts.add("abcd");
                   ts.add("cc");
                   ts.add("cba");
                   ts.add("aaa");
                   ts.add("z");
                   ts.add("hahaha");
 
                   Iterator<String> it = ts.iterator();
 
                   while(it.hasNext())
                   {
                            String s = it.next();
                            System.out.println(s);
                   }
         }
}
 
 
class LenComparator implementsComparator<String>
{
         public int compare(String o1,String o2)
         {
                   int num = new Integer(o2.length()).compareTo(new Integer(o1.length()));
 
                   if(num==0)
                            returno2.compareTo(o1);
                   return num;
         }
}


 

7.2.3泛型类。

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候,

早期定义Object来完成扩展。

现在定义泛型来完成扩展。

 

练习六:泛型定义在类上

 

class Tool
{
         private Worker w;
         public void setWorker(Worker w)
         {
                   this.w= w;
         }
         public Worker getWorker()
         {
                   returnw;
         }
}
*/
 
class Worker
{
 
}
class Student
{
}
//泛型前做法。
class Tool
{
         private Object obj;
         public void setObject(Object obj)
         {
                   this.obj= obj;
         }
         public Object getObject()
         {
                   returnobj;
         }
}
 
class Utils<QQ>
{
         private QQ q;
         public void setObject(QQ q)
         {
                   this.q= q;
         }
         public QQ getObject()
         {
                   returnq;
         }
}
 
 
class GenericDemo3
{
         public static void main(String[] args)
         {
 
                   Utils<Worker>u = new Utils<Worker>();
 
                   u.setObject(newStudent());
                   Worker w = u.getObject();;
                   /*
                   Toolt = new Tool();
                   t.setObject(new Student());
                   Worker w = (Worker)t.getObject();
                   */
         }
}


 

7.2.4泛型方法

 

泛型类定义的泛型,在整个类中有效。如果被方法使用,

那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

 

为了让不同方法可以操作不同类型,而且类型还不确定。

那么可以将泛型定义在方法上。

 

定义在方法上时,放在返回类型的前面,修饰符的后面

例:public  static <W> voidmethod(W t)

 

特殊之处:

静态方法不可以访问类上定义的泛型。

如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

 

练习七:泛型定义在方法上

class Demo<T>
{
         public  void show(T t)
         {
                   System.out.println("show:"+t);
         }
         public<Q> void print(Q q)
         {
                   System.out.println("print:"+q);
         }
         public  static <W> void method(W t)
         {
                   System.out.println("method:"+t);
         }
}
class GenericDemo4
{
         public static void main(String[] args)
         {
                   Demo<String> d = new Demo<String>();
                   d.show("haha");
                   //d.show(4);
                   d.print(5);
                   d.print("hehe");
 
                   Demo.method("hahahahha");
 
 
         }
}


 

练习八:泛型定义在接口上。

interface Inter<T>
{
         voidshow(T t);
}
 
/*
class InterImpl implementsInter<String>
{
         public void show(String t)
         {
                   System.out.println("show:"+t);
         }
}
 
*/
 
class InterImpl<T> implementsInter<T>
{
         public void show(T t)
         {
                   System.out.println("show:"+t);
         }
}
class GenericDemo5
{
         public static void main(String[] args)
         {
 
                   InterImpl<Integer> i = new InterImpl<Integer>();
                   i.show(4);
                   //InterImpl i = new InterImpl();
                   //i.show("haha");
         }
}


7.2.5泛型的高级应用:限定

 

? 通配符。也可以理解为占位符。

 

泛型的限定:适用于泛型扩展用的

 

? extends E: 可以接收E类型或者E的子类型。上限。

 

? super E: 可以接收E类型或者E的父类型。下限

 

 

练习九:泛型的高级应用限定练习

 

import java.util.*;
class GenericDemo6
{
         publicstatic void main(String[] args)
         {
                  
 
                   ArrayList<Person> al = new ArrayList<Person>();
                   al.add(new Person("abc1"));
                   al.add(new Person("abc2"));
                   al.add(new Person("abc3"));
                   //printColl(al);
 
                   ArrayList<Student> al1 = new ArrayList<Student>();
                   al1.add(new Student("abc--1"));
                   al1.add(new Student("abc--2"));
                   al1.add(new Student("abc--3"));
                   printColl(al1);  //ArrayList<? extends Person> al = newArrayList<Student>();error
 
         }
         publicstatic void printColl(Collection<? extends Person> al)
         {
                   Iterator<?extends Person> it = al.iterator();
 
 
                   while(it.hasNext())
                   {
                            System.out.println(it.next().getName());
                   }
         }
         /*
         public static void printColl(ArrayList<?> al)//ArrayList al = newArrayList<Integer>();error
         {
                   Iterator<?> it = al.iterator();
 
 
                   while(it.hasNext())
                   {
                            System.out.println(it.next().toString());
                   }
         }
         */
}
 
class Person
{
         private String name;
         Person(Stringname)
         {
                   this.name= name;
         }
         public String getName()
         {
                   return name;
         }
}
 
class Student extends Person
{
         Student(Stringname)
         {
                   super(name);
         }
 
}


 

 

练习十:泛型限定<?super E>的应用


import java.util.*;
class GenericDemo7
{
         public static void main(String[] args)
         {
                  
                   TreeSet<Student> ts = new TreeSet<Student>(new Comp());
 
                   ts.add(new Student("abc03"));
                   ts.add(new Student("abc02"));
                   ts.add(new Student("abc06"));
                   ts.add(new Student("abc01"));
                  
                   Iterator<Student> it = ts.iterator();
 
                   while(it.hasNext())
                   {
                            System.out.println(it.next().getName());
                   }
                   /**/
 
 
 
                   TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());
 
                   ts1.add(new Worker("wabc--03"));
                   ts1.add(new Worker("wabc--02"));
                   ts1.add(new Worker("wabc--06"));
                   ts1.add(new Worker("wabc--01"));
 
 
                   Iterator<Worker> it1 = ts1.iterator();
 
                   while(it1.hasNext())
                   {
                            System.out.println(it1.next().getName());
                   }
         }
}
 
/*
class StuComp implements Comparator<Student>
{
         public int compare(Student s1,Student s2)
         {
                   return s1.getName().compareTo(s2.getName());
         }
}
 
class WorkerComp implementsComparator<Worker>
{
         public int compare(Worker s1,Worker s2)
         {
                   return s1.getName().compareTo(s2.getName());
         }
}
*/
 
class Comp implementsComparator<Person>
{
         public int compare(Person p1,Person p2)
         {
                   return p2.getName().compareTo(p1.getName());
         }
}
 
 
class Person
{
         private String name;
         Person(Stringname)
         {
                   this.name= name;
         }
         public String getName()
         {
                   return name;
         }
         public String toString()
         {
                   return "person :"+name;
         }
}
 
class Student extends Person
{
         Student(Stringname)
         {
                   super(name);
         }
 
}
 
class Worker extends Person
{
         Worker(Stringname)
         {
                   super(name);
         }
}

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值