Day 15 集合框架
01 TreeSet
02 TreeSet存储自定义对象
03 二叉树
04 实现Comparator方式排序
05 TreeSet练习
06 泛型概述
07 泛型使用
08 泛型类
09 泛型方法
10 静态方法泛型
11 泛型接口
12 泛型限定
13 泛型限定2

01 TreeSet

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

 import java.util.*;
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add("asd");
ts.add("sdfff");
ts.add("abc");
ts.add("Das"); Iterator it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
} }
}

输出是:(按照ASCII码的顺序排序)

Das abc asd sdfff(实际有换行)

02 TreeSet存储自定义对象

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

需求:向TreeSet集合中存贮自定义对象学生
想要根据学生的年龄大小排序。

java中只有实现Comparable接口的类的对象才是可比较的,TreeSet才能对其排序。

注意,排序时,当主要因素相同时,就比较次要因素。

 import java.util.*;
class TreeSetTest2
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add(new Student("wangwu01",12));
ts.add(new Student("wangwu02",44));
ts.add(new Student("wangwu03",16));
ts.add(new Student("wangwu05",52));
ts.add(new Student("wangwu07",22));
ts.add(new Student("wangwu08",22)); 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;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName(){return name;}
public int getAge(){return age;} public int compareTo(Object obj)
{
//用compareTo方法比较后,如果return 0,就视为是相同的对象,不会重复存入
//所以,要注意,主要因素相同时,还要比较次要因素才行
if(!(obj instanceof Student))
throw new RuntimeException("不是学生类!");
Student stu=(Student)obj;
if(this.age>stu.getAge())
return 1;
if(this.age==stu.getAge())
//String类型也实现了Comparable接口
return this.name.compareTo(stu.getName());
return -1;
}
}

03 二叉树

|--TreeSet 可以对集合中的元素进行排序
底层的数据结构是二叉树
保证元素唯一性的依据:
compareTo方法 return 0

二叉排序树:比根元素小的元素作为左孩子节点,比根元素大的元素作为右孩子结点。

作用:减少比较次数,提高排序效率。

04 实现Comparator方式排序

TreeSet排序的第一种方式:让元素自身具备比较性,
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式也成为元素的自然顺序,或者默认顺序。

TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的时候,
这是就需要让集合自身具备比较性。
定义了比较器,将比较器对象作为参宿传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。
比较器的定义:定义一个类,实现Comparator接口,覆盖compare方法。

写项目一定要留有接口,以便以后扩展其他功能。

新需求:按照学生的姓名排序。
分析:由于元素自身的比较性是按照年龄排序,不是我们所需要的。
所以要使用TreeSet第二种比较方式,定义一个比较器。

代码如下:(Student类省略)

 import java.util.*;
class TreeSetTest3
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new myCompare());
ts.add(new Student("wangwu01",12));
ts.add(new Student("wangwu02",44));
ts.add(new Student("wangwu05",16));
ts.add(new Student("wangwu05",52));
ts.add(new Student("wangwu07",22));
ts.add(new Student("wangwu07",22)); 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)
{
if(!(o1 instanceof Student && o2 instanceof Student))
throw new RuntimeException("有参数不是学生类!");
Student s1=(Student)o1;
Student s2=(Student)o2; int num=s1.getName().compareTo(s2.getName());
//如果按姓名排是相同的,就要继续比较其年龄
if(num==0)
{
return (new Integer(s1.getAge())).compareTo(s2.getAge());//return (s1.getAge()-s2.getAge());
}
return num;
}
}

05 TreeSet练习

本练习中比较器也可以定义成匿名内部类。

 /*
练习:按照字符串长度排序。
分析:字符串的自然排序不符合需求,所以使用TreeSet第二中排序方法,定义比较器
*/
import java.util.*;
class TreeSetTest4
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new StrLenComparator() );
ts.add("qwe");
ts.add("qde"); ts.add("z");
ts.add("cv");
ts.add("wdsea"); Iterator it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StrLenComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
if(!(o1 instanceof String && o2 instanceof String))
throw new RuntimeException("有对象不是字符串类型!");
String s1=(String)o1;
String s2=(String)o2; int num=(new Integer(s1.length())).compareTo(s2.length());
//如果字符串长度相同,再比较其内容
if(num==0)
return s1.compareTo(s2);
return num; }
}

06 泛型概述

泛型:JDK 1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制。
(升级的原因:高效,简化,安全)

优点:
1.将运行时期出现的问题ClassCastException,转移到了编译时期,
便于程序员解决问题,使运行时的问题减少,更加安全。
2.避免了强制转换的麻烦。

 import java.util.*;
class GenericDemo
{
public static void main(String[] args)
{
//在创建集合时,就为集合中的元素指明类型,
//一旦存入错误的类型,编译时就会报错
ArrayList<String> al=new ArrayList<String>(); al.add("asss01");
al.add("edcc");
al.add("edscs"); //为迭代器指明类型
//就不用强制转换了
Iterator<String> it=al.iterator();
while(it.hasNext())
{
String s=it.next();
System.out.println(s+":"+s.length());
}
}
}

07 泛型使用

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

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

通常在集合框架中很常见。只要见到<>就要定义泛型。
其实<>就是用来接受类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 import java.util.*;
class GenericDemo2
{
public static void main(String[] args)
{
TreeSet<String> ts=new TreeSet<String>(new LenStrComparator());
ts.add("assd");
ts.add("df");
ts.add("er");
ts.add("dfg"); Iterator<String> it=ts.iterator();
while(it.hasNext())
{
String s=it.next();
System.out.println(s);
} }
}
class LenStrComparator implements Comparator<String>//添加泛型,避免了compare方法中强转的麻烦
{
public int compare(String s1,String s2)
{
//如果想按字符串长度降序输出,则调换s1,s2位置。
int num=(new Integer(s1.length())).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2);
return num;
}
}

08 泛型类

泛型类:
什么时候定义泛型类?
当类中要操作的引用数据类型不确定时,
早期定义Object来完成扩展
现在定义泛型来完成。

 import java.util.*;
class Student
{
}
class Worker
{
}
//泛型出现前的用法 class Tool
{
private Object obj;
public void setObject(Object obj)
{
this.obj=obj;
}
public Object getObject()
{return obj;}
}
//使用泛型的做法
class Utils<T>
{
private T t;
public void setObject(T t)
{
this.t=t;
}
public T getObject()
{
return t;
}
}
class GenericDemo3
{ public static void main(String[] args)
{
Utils<Worker> u=new Utils<Worker>();
Worker w=u.getObject();//不再需要强转了 /*Tool t=new Tool();
t.setObject(new Student());
Worker w=(Worker)t.getObject();
*/
}
}

09 泛型方法

泛型类定义的泛型,在整个类中有效,如果被方法使用,
那么泛型类的对象明确要操作的数据类型后,所有要操作的类型就已经固定了。

为了让不同的方法可以操作不同的类型,而且类型不确定,
那么可以将泛型定义在方法上。

 import java.util.*;
class Demo
{
public <T> void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
}
class GenericDemo4
{
public static void main(String[] args)
{
Demo d=new Demo();
d.show(4);//装箱,拆箱
d.print("hahaha"); }
}

10 静态方法泛型

特殊:
静态方法不可以使用定义在类上的泛型(无法从静态上下文中引用非静态)
如果静态方法操作的方法不确定,可以把泛型定义在方法上。
注意泛型在方法头部中的位置,在修饰符后,返回值类型之前,例如 public static <T> void method()。

11 泛型接口

 /*
泛型定义在接口上
*/
import java.util.*;
interface Inter<T>
{
public void show(T t);
}
class InterImp<T> implements Inter<T>
{
public void show(T t)
{
System.out.println(t);
}
}
class GenericDemo5
{
public static void main(String[] args)
{
InterImp<Integer> i=new InterImp<Integer>();
i.show(5);
}
}

12 泛型限定

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

应用1:

 import java.util.*;
class GenericDemo6
{
public static void main(String[] args)
{
ArrayList<String> al=new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
al.add("abc4"); ArrayList<Integer> al1=new ArrayList<Integer>();
al1.add(2);
al1.add(5);
al1.add(6); printColl(al);
printColl(al1); }
public static void printColl(ArrayList<?> al)//使用通配符,可以操作不同类型的对象。也可以用T
{
Iterator<?> it=al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}

应用2:

泛型的限定
? extends E:可以接受E类型或者E类型的子类,上限。
? super E:可以接受E类型或者E类型的父类,下限。

用到? extends E中的地方:

Collection接口中 :boolean addAll(Collection<? extends e> c)

用到? super E中的地方:

TreeSet类中 :TreeSet(Comparator<?super e> comparator)

 import java.util.*;
class GenericDemo6
{
public static void main(String[] args)
{
ArrayList<Person> al=new ArrayList<Person>();
al.add(new Person("abc01"));
al.add(new Person("abc02"));
al.add(new Person("abc03"));
al.add(new Person("abc04")); //printColl(al); ArrayList<Student> al1=new ArrayList<Student>();
al1.add(new Student("abc--01"));
al1.add(new Student("abc--02"));
al1.add(new Student("abc--03"));
al1.add(new Student("abc--04"));
printColl(al1);
//ArrayList<Person> al=new ArrayList<Student>();Error!
//Person p=new Student();正确的,多态
//ArrayList<Student> al=new ArrayList<Person>(); 也是错误的! 要一致 }
public static void printColl(ArrayList<? extends Person> al)
{
Iterator<? extends Person> it=al.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
class Person
{
private String name;
public Person(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class Student extends Person implements Comparable<Person>//<? super E>
{
public Student(String name)
{
super(name);
}
public int compareTo(Person p)
{
return (this.getName()).compareTo(p.getName());
}
}

13 泛型限定2

泛型限定是扩展用的。
? super E的例子
TreeSet(Comparator<? super E> comparator)一个类父类的比较器类也可用作这个类构造方法的参数
这个例子中Student类和Worker类就都用了它们父类Person的比较器Comp类

 import java.util.*;
class GenericDemo7
{
public static void main(String[] args)
{
TreeSet<Student> ts1=new TreeSet<Student>(new Comp());
ts1.add(new Student("qaz1"));
ts1.add(new Student("qaz3"));
ts1.add(new Student("qaz6")); Iterator<Student> it=ts1.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
} TreeSet<Worker> ts2=new TreeSet<Worker>(new Comp());
ts2.add(new Worker("w--qaz1"));
ts2.add(new Worker("w--qaz3"));
ts2.add(new Worker("w--qaz6")); Iterator<Worker> it2=ts2.iterator();
while(it2.hasNext())
{
System.out.println(it2.next().getName());
}
} }
class Person
{
private String name;
public Person(String name)
{
this.name=name;
}
public String getName()
{
return name;
} public String toString()
{
return "person:"+name;
}
}
class Comp implements Comparator<Person>
{
public int compare(Person p1,Person p2)
{
return (p2.getName()).compareTo(p1.getName());//降序排列
}
}
class Student extends Person
{
public Student(String name)
{
super(name);
} }
class Worker extends Person
{
public Worker(String name)
{
super(name);
}
}

集合3--毕向东java基础教程视频学习笔记的更多相关文章

  1. 多线程--毕向东java基础教程视频学习笔记

    目录 1.多线程运行的安全问题 2.多线程同步代码块 3.同步方法的锁是this 4.静态同步方法的锁是Class对象 5.单例设计模式(面试中的考点) 6.死锁(一个发生死锁的例子) 多线程运行的安 ...

  2. 集合2--毕向东java基础教程视频学习笔记

    Day14 08 LinkedList09 LinkedList练习10 ArrayList练习11 ArrayList练习2 12 HashSet13 HashSet存储自定义对象14 HashSe ...

  3. 集合1--毕向东java基础教程视频学习笔记

    Day14 集合框架01 体系概述02 共性方法03 迭代器04 List集合共性方法05 ListIterator06 List集合具体对象特点07 Vector中的枚举 01 体系概述 集合类为什 ...

  4. IO流05--毕向东JAVA基础教程视频学习笔记

    Day20 10 创建java文件列表11 Properties简述12 Properties存取13 Properties存取配置文件14 Properties练习15 PrintWriter16 ...

  5. IO流01--毕向东JAVA基础教程视频学习笔记

    提要 01 IO流(BufferedWriter)02 IO流(BufferedReader)03 IO流(通过缓冲区复制文本文件)04 IO流(readLine的原理)05 IO流(MyBuffer ...

  6. 网络编程4--毕向东java基础教程视频学习笔记

    Day24 06 自定义浏览器-Tomcat服务端07 自定义图形界面浏览器-Tomcat服务端08 URL-URLConnection09 小知识点10 域名解析 06 自定义浏览器-Tomcat服 ...

  7. 网络编程3--毕向东java基础教程视频学习笔记

    Day24 01 TCP上传图片02 客户端并发上传图片03 客户端并发登录04 浏览器客户端-自定义服务端05 浏览器客户端-Tomcat服务端 01 TCP上传图片 import java.net ...

  8. 网络编程2--毕向东java基础教程视频学习笔记

    Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...

  9. IO流04--毕向东JAVA基础教程视频学习笔记

    Day20 01 File概述02 File对象功能-创建和删除03 File对象功能-判断04 File对象功能-获取05 File对象功能-文件列表106 File对象功能-文件列表207 列出目 ...

随机推荐

  1. 如何添加并设置远程桌面(RD)授权服务器

    上一篇日志中介绍了如何将现成的远程桌面授权服务器添加到对应的远程桌面回话主机中. 本篇日志将引导您如何添加配置相应的远程桌面授权服务器,这样就可以根据所购买的授权类型和授权级别添加需要甚至" ...

  2. MySQL入门04-MySQL主从配置

    1.主节点授权同步用户 2.主节点修改配置文件 3.从节点修改配置文件 4.主节点锁定后查看状态 5.从节点配置并启动同步.查看状态 6.主节点解锁并验证从节点是否正常同步 环境:CentOS 6.7 ...

  3. 关于JavaScript预编译和执行顺序以及函数引用类型的思考

    昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...

  4. KVM的前世今生

    1.虚拟化技术的演变过程:软件模拟.虚拟化层翻译.容器虚拟化三个阶段 (1)软件模拟的技术方式 软件模拟是通过软件完全模拟CPU.网卡.芯片组.磁盘等计算机硬件,因为是软件模拟,所以理论上可以模拟任何 ...

  5. js实现可拖拽的div

    前言 下午忙里偷闲想写一个可拖拽的例子,留在脑海里一直都是三个事件mouseDown,mouseUp,mouseMove, 但从没有动手实践过,今天想起了自己实践了并学习了张鑫旭的demo实现. 学习 ...

  6. 【JUC】JDK1.8源码分析之ConcurrentHashMap(一)

    一.前言 最近几天忙着做点别的东西,今天终于有时间分析源码了,看源码感觉很爽,并且发现ConcurrentHashMap在JDK1.8版本与之前的版本在并发控制上存在很大的差别,很有必要进行认真的分析 ...

  7. [开源ORM] SqliteSugar 3.x .net Core版本成功上线

    SqliteSqlSugar 3.X API 作为支持.NET CORE 为数不多的ORM之一,除了具有优越的性能外,还拥有强大的功能,不只是满足你的增,删,查和改.实质上拥有更多你想像不到的功能,当 ...

  8. 分享一个UI与业务逻辑分层的框架(三)

    序言 前两篇讲解了UIMediator框架的使用及具体原理代码.本篇讲述MediatorManager的实现代码及展望. MediatorManager MediatorManager的作用有两点: ...

  9. luogg_java学习_10_异常_反射

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 异常_反射 异常 异常就是导致程序中断执行的一段指令流 ...

  10. ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理

    话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...