十、泛型限定

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、TreeSet1.1、TreeSet

Set:hashSet:数据结构是哈希表。线程是非同步的。

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

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

TreeSet: 可以去Set集合中的元素时行 排序。

使用二叉树的数据结构。

保证元素唯一性的依据:compareTo()方法return 0

使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator进行排序,具体取决于使用的构造方法。

示例一、

packagecom.pb.treeset.demo1;importjava.util.Iterator;importjava.util.TreeSet;/***

*@authorDenny

* TreeSet

* 可以对Set集合的元素进行自然排序

**/publicclassTreeSetDemo1 {publicstaticvoidmain(String[] args) {

TreeSet ts=newTreeSet();

ts.add("abc");

ts.add("aah");

ts.add("cda");

ts.add("bca");

ts.add("Dca");for(Iterator it=ts.iterator();it.hasNext();){

System.out.PRintln(it.next());

}

}

}

结果:

Dca

aah

abc

bca

cda

示例二、使用对象

二、Comparable

TreeSet排序:

第一种方式,让元素自身具备比较性,元素实现Comparable接口,重写compareTo()方法。自然顺序排序

2.1、Comparable接口

public interfaceComparable<T>

此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。

使用TreeSet存多个对象时,要在该对象类中实现Comparable接口,以实现TreeSet的排序,不然就会报java.lang.ClassCastException:

cannot be cast to java.lang.Comparable

方法摘要int

compareTo(T o)

比较此对象与指定对象的顺序。

参数:o- 要比较的对象。返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。抛出:ClassCastException- 如果指定对象的类型不允许它与此对象进行比较。

排序时:当主要条件相同时,要判断次要条件。

packagecom.pb.treeset.demo1;publicclassPersonimplementsComparable{privateString name;//姓名privateintage;//年龄privateString gender;//性别publicPerson() {super();//TODO Auto-generated constructor stub}publicPerson(String name,intage, String gender) {super();this.name =name;this.age =age;this.gender =gender;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}publicString getGender() {returngender;

}publicvoidsetGender(String gender) {this.gender =gender;

}//显示所有属性publicvoidshow(){

System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);

}/** 按照年龄大小排序,年龄相同按姓名排序*/@OverridepublicintcompareTo(Object obj) {if(!(objinstanceofPerson)){try{thrownewException("不是人类对象");

}catch(Exception e) {

e.printStackTrace();

}

}

Person p=(Person)obj;if(this.age>p.age){return1;

}elseif(this.age<p.age){return-1;

}else{returnthis.name.compareTo(p.name);

}

}

}

packagecom.pb.treeset.demo1;importjava.util.Iterator;importjava.util.TreeSet;publicclassTreeSetDemo2 {publicstaticvoidmain(String[] args) {

Person p1=newPerson("lisi007",19,"man");

Person p2=newPerson("lisi003",20,"woman");

Person p3=newPerson("zhangsan002",19,"man");

Person p4=newPerson("abc009",20,"woman");

Person p5=newPerson("ndd011",19,"man");

Person p6=newPerson("QQ005",16,"woman");//声明TreeSet集合TreeSet<Person>ts=newTreeSet<Person>();//添加对象元素ts.add(p1);

ts.add(p2);

ts.add(p3);

ts.add(p4);

ts.add(p5);

ts.add(p6);//遍历for(Iterator<Person> it=ts.iterator();it.hasNext();){

Person p=it.next();

p.show();

}

}

}

结果:

姓名:qq005........年龄:16...........性别:woman

姓名:lisi007........年龄:19...........性别:man

姓名:ndd011........年龄:19...........性别:man

姓名:zhangsan002........年龄:19...........性别:man

姓名:abc009........年龄:20...........性别:woman

姓名:lisi003........年龄:20...........性别:woman

示例:如果按存入顺序取出只需要CompareTo方法return 1

packagecom.pb.treeset.demo1;publicclassPersonimplementsComparable{privateString name;//姓名privateintage;//年龄privateString gender;//性别publicPerson() {super();//TODO Auto-generated constructor stub}publicPerson(String name,intage, String gender) {super();this.name =name;this.age =age;this.gender =gender;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}publicString getGender() {returngender;

}publicvoidsetGender(String gender) {this.gender =gender;

}//显示所有属性publicvoidshow(){

System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);

}/** 按照年龄大小排序,年龄相同按姓名排序*/@OverridepublicintcompareTo(Object obj) {//存出顺序return1;//倒序//return -1//如果返回0就只有一个元素}

}

三、3.1、实现指定的比较器实现Comparator 接口,重写compare方法

第二种方式:当元素自身不具备比较性时或者具备的比较性不是所需要的。

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

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

构造方法摘要TreeSet()

构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。

TreeSet(Collection<? extends E> c)

构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。

TreeSet(Comparator<? super E> comparator)

构造一个新的空 TreeSet,它根据指定比较器进行排序。

TreeSet(SortedSet<E> s)

构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。

定义比较器,将比较器对象 作为参数转递给集合TreeSet的构造方法

示例一、

packagecom.pb.treeset.demo2;publicclassPerson{privateString name;//姓名privateintage;//年龄privateString gender;//性别publicPerson() {super();//TODO Auto-generated constructor stub}publicPerson(String name,intage, String gender) {super();this.name =name;this.age =age;this.gender =gender;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}publicString getGender() {returngender;

}publicvoidsetGender(String gender) {this.gender =gender;

}//显示所有属性publicvoidshow(){

System.out.println("姓名:"+this.name+"........年龄:"+this.age+"...........性别:"+this.gender);

}

}

比较器

packagecom.pb.treeset.demo2;importjava.util.Comparator;/*** 比较器,实现Comparator接口,

* 并重写compare方法

*@authorAdministrator

**/publicclassMyComparetorimplementsComparator<Person>{/** 按姓名排序,如果姓名相同,按年龄排序*/@Overridepublicintcompare(Person p1, Person p2) {//比较姓名intnum=p1.getName().compareTo(p2.getName());//如果姓名相同if(num==0){//比较年龄returnnewInteger(p1.getAge()).compareTo(newInteger(p2.getAge()));

}//返回结果returnnum;

}

}

packagecom.pb.treeset.demo2;importjava.util.Iterator;importjava.util.TreeSet;publicclassTreeSetDemo3 {publicstaticvoidmain(String[] args) {//声明TreeSet集合,并将比较器传入构造方法TreeSet<Person> ts=newTreeSet<Person>(newMyComparetor());//添加元素ts.add(newPerson("lisi010",21,"man"));

ts.add(newPerson("lisi010",19,"man"));

ts.add(newPerson("lisi007",21,"woman"));

ts.add(newPerson("lisi002",16,"man"));

ts.add(newPerson("lisi022",21,"woman"));

ts.add(newPerson("lisi010",16,"man"));//遍历for(Iterator<Person> it=ts.iterator();it.hasNext();){

Person p=it.next();

p.show();

}

}

}

姓名:lisi002........年龄:16...........性别:man

姓名:lisi007........年龄:21...........性别:woman

姓名:lisi010........年龄:16...........性别:man

姓名:lisi010........年龄:19...........性别:man

姓名:lisi010........年龄:21...........性别:man

姓名:lisi022........年龄:21...........性别:woman

示例二、

packagecom.pb.treeset.demo2;importjava.util.Comparator;importjava.util.Iterator;importjava.util.TreeSet;/** 按照字符串长度排序*/publicclassTreeSetDemo4 {publicstaticvoidmain(String[] args) {

TreeSet<String> ts=newTreeSet<String>(newMyCompare());

ts.add("abcd");

ts.add("cc");

ts.add("cba");

ts.add("Cba");

ts.add("z");

ts.add("NBA");

ts.add("hehe");

ts.add("A");for(Iterator<String> it =ts.iterator();it.hasNext();){

System.out.println(it.next());

}

}

}/** 比较器*/classMyCompareimplementsComparator<String>{

@Overridepublicintcompare(String s1, String s2) {//比较长度intlen=newInteger(s1.length()).compareTo(newInteger(s2.length()));//如果长度相同,比较内容if(len==0){returns1.compareTo(s2);

}returnlen;

}

}

四、泛型4.1、泛型概述

JDK1.5出现新特性,用于解决安全问题,是一个安全机制

如:ArrayList<String> a1=new ArrayList<String>();

声明一个字符串类型的arraylist容器,只能存String类型

优点:将运行时期出现的问题ClassCastException,转移到了编译时期。

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

避免了强制类型转换麻烦。

packagecom.pb.fanxing.demo1;importjava.util.ArrayList;importjava.util.Iterator;publicclassArryListDemo1 {publicstaticvoidmain(String[] args) {//声明一个Arraylist集合,只能存放String类型ArrayList<String> al=newArrayList<String>();

al.add("abcd");

al.add("adc");

al.add("NBA");

al.add("CFO");//遍历Iterator<String> it=al.iterator();while(it.hasNext()){

String str=it.next();

System.out.println(str);

}

}

}

五、泛型使用5.1、使用泛型

通过<>来定义泛型

通常在集合框架中很常见,只要见到<>就要定义泛型。

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

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

packagecom.pb.fanxing.demo1;importjava.util.Comparator;importjava.util.Iterator;importjava.util.TreeSet;//倒序排列publicclassDemo2 {publicstaticvoidmain(String[] args) {

TreeSet<String> ts=newTreeSet<String>(newMyCompare());

ts.add("abcd");

ts.add("cc");

ts.add("cba");

ts.add("Cba");

ts.add("z");

ts.add("NBA");

ts.add("hehe");

ts.add("A");for(Iterator<String> it =ts.iterator();it.hasNext();){

System.out.println(it.next());

}

}

}/** 比较器*/classMyCompareimplementsComparator<String>{

@Overridepublicintcompare(String s1, String s2) {//比较长度//倒序排列intlen=newInteger(s2.length()).compareTo(newInteger(s1.length()));//如果长度相同,比较内容if(len==0){returns2.compareTo(s1);

}returnlen;

}

}

hehe

abcd

cba

NBA

Cba

cc

z

A

六、泛型类6.1、泛型类的使用

packagecom.pb.fanxing.demo2;/*** 当类中要操作的引用数据类型不确定的时候

* 早期定主Object来完成扩展

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

**/classPerson{privateString name;privateintage;publicPerson() {super();//TODO Auto-generated constructor stub}publicPerson(String name,intage) {super();this.name =name;this.age =age;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}

}classStudentextendsPerson{privateintid;publicintgetId() {returnid;

}publicvoidsetId(intid) {this.id =id;

}

}/** 泛型类*/classUtils<T>{privateT t;publicvoidsetT(T t){this.t=t;

}publicT getT(){returnt;

}

}publicclassGenericDemo1 {publicstaticvoidmain(String[] args) {

Utils<Person> u=newUtils<Person>();

u.setT(newPerson("张三",23));

Person person=u.getT();

System.out.println(person.getName()+"......"+person.getAge());

}

}

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

泛型类的对象明克要操作的具体类型后,所有 要操作的类型已经固定

七、泛型方法7.1、泛型类的方法

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

可以将泛型定义在方法上

packagecom.pb.fanxing.demo2;/*** 泛型方法

**/classDemo{public<T>voidshow(T t){

System.out.println("show:"+t);

}public<T>voidprint(T t){

System.out.println("print:"+t);

}

}publicclassGenericDemo2 {publicstaticvoidmain(String[] args) {

Demo d=newDemo();

d.show(4);

d.print("hehe");

d.show("hello");

d.print(3.4);

}

}

结果:

show:4print:hehe

show:hello

print:3.4

八、静态泛型方法8.1、静态泛型方法

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

如果静态方法访问的类型不确定,可以将泛型定义在方法上

packagecom.pb.fanxing.demo2;classTool<T>{//和类上的泛型一至public<T>voidshow(T t){

System.out.println("show:"+t);

}//单独的和类上的不一样,但也可以使用类上的public<Q>voidprint(Q q){

System.out.println("print:"+q);

}//单独的和类上的不一样因为是static的,不能和类上的一样publicstatic<W>voidmethod(W t){

System.out.println("static:"+t);

}

}publicclassGenericStaticDemo {publicstaticvoidmain(String[] args) {//定义字符串Tool<String> t=newTool<String>();//传入字符串t.show("hehe");//传入字符串t.print("dfsds");//传入doublet.print(2323.3);//传入字符串t.method("ffff");//传入intt.method(222);

}

}

结果:

show:hehe

print:dfsds

print:2323.3static:ffffstatic:222

九、泛型接口9.1、泛型接口

packagecom.pb.fanxing.demo2;interfaceTest<T>{publicvoidshow(T t);

}classTestImpl<T>implementsTest<T>{

@Overridepublicvoidshow(T t) {

System.out.println(t);

}

}publicclassGenericDemo3 {publicstaticvoidmain(String[] args) {

Test<String> test=newTestImpl<String>();

test.show("hello");

Test<Integer> test1=newTestImpl<Integer>();

test1.show(332);

}

}

十、泛型限定10.1、泛型限定

使用<?>来占位

packagecom.pb.fanxing.demo2;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;publicclassGenericDemo4 {publicstaticvoidmain(String[] args) {

List<String> list=newArrayList<String>();

list.add("aa");

list.add("ab");

list.add("ac");

List<Integer> list1=newArrayList<Integer>();

list1.add(3);

list1.add(1);

list1.add(5);

print(list);

print(list1);

}/*public static void print(List<?> list){ //不确定类型

Iterator<?> it=list.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

}*///使用泛型Tpublicstatic<T>voidprint(List<T> list){//不确定类型Iterator<T> it=list.iterator();while(it.hasNext()){

T t=it.next();//使用泛型可以操作对象System.out.println(t);

}

}

}

aa

ab

ac

3

1

5

10.2、上限和下限

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

泛型的限定

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

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

packagecom.pb.fanxing.demo2;importjava.util.ArrayList;importjava.util.Iterator;classPerson{privateString name;privateintage;publicPerson(String name,intage){this.name=name;this.age=age;

}publicString getName(){returnname;

}publicintgetAge(){returnage;

}

}classStudentextendsPerson{publicStudent(String name,intage){super(name,age);

}

}publicclassGenericDemo5 {publicstaticvoidmain(String[] args) {

ArrayList<Person> a1=newArrayList<Person>();

a1.add(newPerson("abc1",23));

a1.add(newPerson("abc2",13));

a1.add(newPerson("abc3",33));

ArrayList<Student> a2=newArrayList<Student>();

a2.add(newStudent("abc--1",23));

a2.add(newStudent("abc--2",13));

a2.add(newStudent("abc--3",33));

print(a1);

print(a2);

}publicstaticvoidprint(ArrayList<?extendsPerson> list){//代表Person和Person的子类Iterator<?extendsPerson> it=list.iterator();while(it.hasNext()){

Person p=it.next();

System.out.println(p.getName()+"..."+p.getAge());

}

}

}//结果abc1...23abc2...13abc3...33abc--1...23abc--2...13abc--3...33

下限

packagecom.pb.fanxing.demo2;importjava.util.ArrayList;importjava.util.Comparator;importjava.util.Iterator;importjava.util.Set;importjava.util.TreeSet;classPerson{privateString name;privateintage;publicPerson(String name,intage){this.name=name;this.age=age;

}publicString getName(){returnname;

}publicintgetAge(){returnage;

}

}classStudentextendsPerson{publicStudent(String name,intage){super(name,age);

}

}publicclassGenericDemo5 {publicstaticvoidmain(String[] args) {

TreeSet<Student> ts=newTreeSet<Student>(newMyCompare());

ts.add(newStudent("abc--5",23));

ts.add(newStudent("abc--2",13));

ts.add(newStudent("abc--3",33));

print(ts);

}publicstaticvoidprint(Set<?extendsPerson> list){//代表Person和Person的子类Iterator<?extendsPerson> it=list.iterator();while(it.hasNext()){

Person p=it.next();

System.out.println(p.getName()+"..."+p.getAge());

}

}

}classMyCompareimplementsComparator<Person>{

@Overridepublicintcompare(Person p1, Person p2) {returnp1.getName().compareTo(p2.getName());

}

}//结果:abc--2...13abc--3...33abc--5...23

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航