博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
黑马程序员_<<泛型>>
阅读量:5254 次
发布时间:2019-06-14

本文共 7550 字,大约阅读时间需要 25 分钟。

--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! --------------------

 

1.     泛型

     1.概述

 

           泛型是为了解决了集合中存储对象安全问题,如果集合中存数了不同类型的对象,那么读取出来后,操作取出的对象以为不知道类型,会出现安全问题,但是这不会在编译时期提示错误,而是会在运行时期出现问题,所以泛型会把运行时期的错误移到了编译时期,那么错误就会避免。

     2.集合中的泛型

           在集合中都会存在泛型,下同时迭代器中也定义了泛型,在读取出来后,我们也要指定迭代器的类型,这样我们就不需要强制类型转换了,因为迭代器中就指定了类型,所以读取出来的对象类型也就是我们指定的类型。

 

 

package www.fuxi.jihe; import java.util.ArrayList;import java.util.Iterator; public class fanxingDemo {   public static void main(String[] args) {     ArrayList
list = new ArrayList
(); list.add("zhangsan");// 在这里必须传入的String对象,如果不是那么编译会出错误 list.add("lisi"); Iterator
it = list.iterator();// 在这里也要指定迭代器的类型 while (it.hasNext()) { String s = it.next();// 在这里不需要强制类型转换为String了,因为迭代器已经指定了类型 System.out.println(s); } } }结果:zhangsanlisi

 

 

 

2.     自定义泛型类

自定义的泛型类,可以按照我们随意要求指定类型

 

 

package www.fuxi.jihe; /** * 在此类型定义了一个泛型,这个字母可以随便定义当创建了此类的对象,那么就需要指定泛型的类型,那么里面的成员泛型就统一指定了 */package www.fuxi.jihe; public class Demo
{ private T t; public void set(T t){//此方法是和类上的泛型一起变化 this.t=t; System.out.println("set:"+t); } public static void main(String [] agrs){ Demo
d=new Demo
(); d.set("123"); } }结果:set:123

 

 

3.     泛型方法

1.     一个泛型

   

public class Demo
{ public void show(T t) { System.out.println("show:" + t); } public void print(T t) { System.out.println("print:" + t); } public static void main(String[] args) { Demo
d = new Demo
(); d.show("hello"); d.print("world"); // d.show(new // Integer(2));//在这里编译出错,因为d对象泛型已经指定了是String类型,所以参数全部是String类型 System.out.println("-----------"); Demo
d1 = new Demo
(); d1.show(new Integer(3)); d1.print(new Integer(6)); } }结果:show:helloprint:world-----------show:3print:6

 

 

 

2.     多个泛型

 

 

package www.fuxi.jihe; public class Demo
{ public void set(T t){//此方法是和类上的泛型一起变化 System.out.println("set:"+t); } public
void get(Q q){//此方法上的泛型是和类上的泛型无关,可以是任意类型 System.out.println("get:"+q); } public static void main(String [] agrs){ Demo
d=new Demo
(); d.set("123"); d.get("abc"); d.get(5); } } 结果:set:123get:abcget:5

 

从结果可以看出,这个类中既有和类上的泛型一起变化的,也有自己特有的方法,例如:get()方法上的泛型,可以和类上的一样也可以不一样。

 

3.静态方法上的泛型

  把泛型定义在返回值和修饰符之间

静态方法上的泛型的定义需要自己定义,不要和类上的泛型统一,因为静态方法只要是类一加载就生成,如果和类上的泛型统一的话,在静态方法加载的时候,没有对象生成,也就没有指定泛型的类型,那么就会出错,这些都和泛型定义出现的时间有关。

 

 

package www.fuxi.jihe; public class Demo
{ public static
void show(Q q){//这里不要和类上的泛型统一 System.out.println("show:"+q); } public static void main(String [] agrs){ Demo.show("hello"); } }结果:show:hello

 

4.     接口泛型

     在接口上自定义泛型

 

 

package www.fuxi.jihe; interface inter
{ void show(T t);} /* 第一种实现泛型接口,在接口上指定泛型类型 */public class Demo implements inter
{ public void show(String t) { System.out.println("show:" + t); } public static void main(String[] agrs) { Demo d = new Demo(); d.show("hellowrold"); }}结果:show:hello world

 

 

下面是在对象是上指定泛型类型

 

 

package www.fuxi.jihe; interface inter
{ void show(T t);} /* 第二种实现泛型接口,在接口上不定义泛型,而是在对象上指定泛型类型 */public class Demo
implements inter
{ public void show(T t) { System.out.println("show:" + t); } public static void main(String[] agrs) { Demo
d = new Demo
(); d.show(3); }} 结果:show:3

 

5.     泛型的高级应用

1.     通配符

通配符用?表示,也叫占位符,可以表示任意类型

 

 

package www.fuxi.jihe; import java.util.ArrayList;import java.util.Iterator; public class Demo {   /*在这里泛型类型使用通配符表示,表次是此可以传入任意类型*/   public void show(ArrayList
list) { Iterator
it = list.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } public static void main(String[] agrs) { Demo d = new Demo(); ArrayList
l1 = new ArrayList
(); l1.add("abc"); l1.add("123"); l1.add("ased"); d.show(l1); System.out.println("---------"); ArrayList
l2 = new ArrayList
(); l2.add(1); l2.add(2); l2.add(3); d.show(l2); }}结果:abc123ased---------123

 

 

但是也可以使用另一中方式表示,但是其有缺点,不能表示一个范围类型,通配符可以表示一个类型范围,详细“2.参考通配符设置上下限”

 

 

package www.fuxi.jihe; import java.util.ArrayList;import java.util.Iterator; public class Demo {   /* 在这里泛型类型使用通配符表示,表次是此可以传入任意类型 */   public 
void show(ArrayList
list) { Iterator
it = list.iterator(); while (it.hasNext()) { T t= it.next(); System.out.println(t); } } public static void main(String[] agrs) { Demo d = new Demo(); ArrayList
l1 = new ArrayList
(); l1.add("abc"); l1.add("123"); l1.add("ased"); d.show(l1); System.out.println("---------"); ArrayList
l2 = new ArrayList
(); l2.add(1); l2.add(2); l2.add(3); d.show(l2); }} 结果:abc123ased---------123

 

从结果上可以看出,结果和使用通配符是一样的,这个好处可以把对象取出来,可以进行操作,T t= it.next();但是使用通配符的话,就不能进行此操作,但是通配符可以设置上下限。

2.     通配符设置上下限

? extends E :?表示可以是E类型或者是E的子类,这是设置的上限

? super E:?表示的可以是E类型或者E的父类类型,这是设置的下限

 

设置上限

 

 

package www.fuxi.jihe; import java.util.ArrayList;import java.util.Iterator; class door {  privateString name;   publicdoor(String name) {       this.name= name;  }   publicString toString() {       returnthis.name;  }} class tieDoor extends door {// 继承了door类  publictieDoor(String name) {       super(name);  }} public class fanxingDemo {  publicvoid show(ArrayList
list) {// 设置类泛型的限,可以是door类型或者是door的子类型 Iterator
it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } publicstatic void main(String[] args) { fanxingDemod = new fanxingDemo(); ArrayList
list = new ArrayList
(); list.add(newtieDoor("door-1")); list.add(newtieDoor("door-2")); list.add(newtieDoor("door-3")); d.show(list); } }结果:door-1door-2door-3

 

 

设置下限:

 

TreeSet(Comparator<?super E> comparator)

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

我们就根据这个比较器看看设置下限:

 

package www.fuxi.jihe; import java.util.ArrayList;import java.util.Comparator;import java.util.Iterator;import java.util.TreeSet; class door {  privateString name;   publicdoor(String name) {       this.name= name;  }   publicString toString() {       returnthis.name;  }  publicString getName(){       returnthis.name;  }} class tieDoor extends door {// 继承了door类  publictieDoor(String name) {       super(name);  }} class MyCom implements Comparator
{ publicint compare(door o1, door o2) { returno1.getName().compareTo(o2.getName()); } }public class fanxingDemo { publicstatic void main(String[] args) { fanxingDemod = new fanxingDemo(); TreeSet
list = new TreeSet
(new MyCom()); list.add(newtieDoor("door-3")); list.add(newtieDoor("door-1")); list.add(newtieDoor("door-2")); Iterator
it=list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }结果:door-1door-2door-3

 

从结果可以看出,已经比较了,但是设置的比较器是父类型,但是TreeSet集合设置的door的子类型,也可以排序,就是可以是下限或者是下限的父类型

可以是tieDoor类型或者tieDoor的父类型,都可以进行比较

假如又有一个类继承了door类,那么此子类对象添加到在TreeSet中,也可以使用当前的比较器进行排序。

--------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------------------

转载于:https://www.cnblogs.com/pangblog/p/3341900.html

你可能感兴趣的文章
针对sl的ICSharpCode.SharpZipLib,只保留zip,gzip的流压缩、解压缩功能
查看>>
【转】代码中特殊的注释技术——TODO、FIXME和XXX的用处
查看>>
【SVM】libsvm-python
查看>>
C++循环单链表删除连续相邻重复值
查看>>
Jmeter接口压力测试,Java.net.BindException: Address already in use: connect
查看>>
ASP.NET使网页弹出窗口不再困难
查看>>
Leetcode Balanced Binary Tree
查看>>
Leetcode 92. Reverse Linked List II
查看>>
windown快速安装xgboost
查看>>
Linux上安装Libssh2
查看>>
九.python面向对象(双下方法内置方法)
查看>>
go:channel(未完)
查看>>
[JS]递归对象或数组
查看>>
LeetCode(17) - Letter Combinations of a Phone Number
查看>>
Linux查找命令对比(find、locate、whereis、which、type、grep)
查看>>
路由器外接硬盘做nas可行吗?
查看>>
python:从迭代器,到生成器,再到协程的示例代码
查看>>
Java多线程系列——原子类的实现(CAS算法)
查看>>
在Ubuntu下配置Apache多域名服务器
查看>>
多线程《三》进程与线程的区别
查看>>