黑马程序员-泛型

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------


定义:

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。

 

 

泛型:是提供给编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入。但是泛型在运行的时候是没有作用的。

 

 

编译器在编译带类型说明的集合的时候会去掉类型信息,使程序运行效率不受影响,对于参数化的类型,getClass()方法的返回值和原始类型完全一致,由于编译生成的字节码信息会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型数据。例如:用反射得到集合,在调用其add方法,就可以填写如其他类型。

 

 

ArrayList  <E> ArrayList  <Integer>  类引用中设计的术语

ArrayList  <E> 叫做泛型类型

                            里面的E称为类型变量或类型参数

ArrayList  <Integer>   叫做参数化类型

                                     里面的Inerger叫做参数实例或实际参数类型

ArrayList     叫做原始类型

 

参数话类型和原始类型的兼容性

 

参数化类型可以引用原始类型对象,但是编译器会警告

Coollection  <String>  c = new Vertor();

 

原始类型可以引用一个参数化类型对象,但是也会报警

Collection  c = new Vertor<String>();

 

类型化参数不考虑类型参数的继承关系(一下两种方式都是错误的)

Vector  <String>  v = new Vertor<Oblect>();

Vertor  <Object>  v = new Vertor<String>();

 

在创建数组实例的时候,数组的元素不能使用参数化的类型

例如:Vector  <Integer>  vList [] = new Vector<Titrger>[10];

//这是错的

 

通配符:使用“?”可以引用其他各种参数化的类型,详细见下面的转载。

 

 

 

规则和限制:

 

1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

3、泛型的类型参数可以有多个。

4、泛型的参数类型可以使用extends语句,例如<T extendssuperclass>。习惯上称为有界类型

5、泛型的参数类型还可以是通配符类型。例如Class<?> classType =Class.forName("java.lang.String");

泛型还有接口、方法等等,内容很多,需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子(根据看的印象写的),实现同样的功能,一个使用了泛型,一个没有使用,通过对比,可以很快学会泛型的应用,学会这个基本上学会了泛型70%的内容。

例子一:使用了泛型

classGen<T> {

private T ob; //定义泛型成员变量

public Gen(T ob){

this.ob = ob;

}

public T getOb(){

return ob;

}

public voidsetOb(T ob) {

this.ob = ob;

}

public voidshowType() {

System.out.println("T的实际类型是: " + ob.getClass().getName());

}

}

public classGenDemo {

public staticvoid main(String[] args){

//定义泛型类Gen的一个Integer版本

Gen<Integer>intOb=new Gen<Integer>(88);

intOb.showType();

int i=intOb.getOb();

System.out.println("value=" + i);

System.out.println("----------------------------------");

//定义泛型类Gen的一个String版本

Gen<String>strOb=new Gen<String>("Hello Gen!");

strOb.showType();

Strings=strOb.getOb();

System.out.println("value=" + s);

}

}

例子二:没有使用泛型

class Gen2 {

private Objectob; //定义一个通用类型成员

publicGen2(Object ob) {

this.ob = ob;

}

public ObjectgetOb() {

return ob;

}

public voidsetOb(Object ob) {

this.ob = ob;

}

public voidshowTyep() {

System.out.println("T的实际类型是: " + ob.getClass().getName());

}

}

public classGenDemo2 {

public staticvoid main(String[] args) {

//定义类Gen2的一个Integer版本

Gen2 intOb = newGen2(new Integer(88));

intOb.showTyep();

int i =(Integer) intOb.getOb();

System.out.println("value=" + i);

System.out.println("---------------------------------");

//定义类Gen2的一个String版本

Gen2 strOb = newGen2("Hello Gen!");

strOb.showTyep();

String s =(String) strOb.getOb();

System.out.println("value=" + s);

}

}

运行结果:

两个例子运行Demo结果是相同的,控制台输出结果如下:

T的实际类型是:

java.lang.Integer

value= 88

----------------------------------

T的实际类型是: java.lang.String

value= HelloGen!

Process finishedwith exit code 0

 

 

 

 

以下为转载

 4通配符

1

问题:l定义一个方法,接收一个任意集合,并打印出集合中的所有元素,如下所示:

错误方式:

1

void print (Collection<Object> c) {  

2

          for (Object : c) {

 

3

                System.out.println(e);

4

          }

 

5

}

正确方式:

01

package com.itcast.generic;

02

import java.util.ArrayList;

 

03

import java.util.Collection;

04

 

 

05

public class GenericTest3 {

06

    public static void main(String[] args) {

 

07

        Collection<String> c = new ArrayList<String>();

08

        Collection<Integer> c1 = new ArrayList<Integer>();

 

09

        printCollection(c);

10

        printCollection(c1);

 

11

    }

12

    public static void printCollection(Collection<?> c){

 

13

        //c.add(1);     在方法体内不能调用与类型相关的方法,例如add()方法

14

        c.size();      //查看API,size方法与类型不相关.

 

15

        for(Object obj:c){

16

            System.out.println(obj);

 

17

        }

18

    }

 

19

}

1

l.此种形式下需要注意的是:由于print方法c参数的类型为Collection<?>,即表示一种不确定的类型,因此在方法体内不  能调用与类型相关的方法,例如add()方法。

 

2

2.总结:使用?通配符主要用于引用对象,使用了?通配符,就只能调对象与类型无关的方法,不能调用对象与类型有关的方法

 有限制的通配符

     a.限定通配符的上边界:(?必须是Number的子类)

     b.限定通配符的下边界 : (?必须是Integer的父类)

        C.限定范围总是包括自己

泛型的通配符扩展应用案例

1

遍历一个Map集合:

01

package com.itcast.generic;

 

02

import java.util.HashMap;

03

import java.util.Map;

 

04

/**

05

 遍历Map集合

 

06

 * @author Say

07

 *

 

08

 */

09

public class IteratorMap {

 

10

    public static void main(String[] args) {

11

        Map<String,Integer> map = new HashMap<String, Integer>();

 

12

        map.put("itcast", 1);

13

        map.put("flx", 50);

 

14

        map.put("黑马", 41);

15

        for(Map.Entry<String, Integer> entry:map.entrySet()){

 

16

            System.out.println(entry.getKey()+"-->"+entry.getValue());

17

        }

 

18

    }

19

}

自定义泛型方法

1

Java中的泛型没有C++中模版强大的原因: Java中泛型在编译器中实现的,生成字节码的过程当中会擦除泛型。

泛型方法定义规则:

Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T>,T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。

例如:

 public static <T> void doxx(T t);

泛型方法定义注意问题:

    只有对象类型才能作为泛型方法的实际参数。

   在泛型中可以同时有多个类型.

  例如:

   public static <K,V> V getValue(K key) { return map.get(key);}

   public static <K extends Annotation> void getXX(){}

   public static <K extends Annotation & Cloneable> voidgetXX(){}

 

01

package com.itcast.generic;

02

/**

 

03

 *  编写一个泛形方法,实现数组元素的交换。

04

 */

 

05

public class SwapArray {

06

    public static void main(String[] args) {

 

07

        //对于数组中的int类型不会自动装箱和拆箱

08

        swap(new String[]{"a","bncd","fdsafdsa"}, 2, 0);

 

09

        swap(new Integer[]{15,25,30,25,47}, 2, 4);

10

    }

 

11

    public static <T> void swap(T[] arr,int x,int y){

12

        T temp = arr[x];

 

13

        arr[x] = arr[y];

14

        arr[y] = temp;

 

15

    }

16

}

自定义泛型类

  如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型)

  语法格式如下:

  public classGenericDao<T> {

     private T field1;

     public void save(T obj){}

     public T getId(int id){}

  }

   注意: 静态方法不能使用类定义的泛形,而应单独定义泛形。先使用类级别的泛型.

    泛形的典型应用:BaseDao

01

package com.itcast.generic;

02

import java.util.Set;

 

03

 

04

public class GenericDao<T> {

 

05

    public void add(T t){

06

         

 

07

    }

08

    public T findById(int id){

 

09

        return null;

10

    }

 

11

    public void delete(T t){

12

    }

 

13

    public void update(T t){

14

    }

 

15

    public Set<T> findByConditions(String where){

16

        return null;

 

17

    }

18

}

8.通过反射获取泛型的实际类型参数

01

package com.itcast.generic;

02

 

 

03

import java.lang.reflect.Method;

04

import java.lang.reflect.ParameterizedType;

 

05

import java.lang.reflect.Type;

06

import java.util.Date;

 

07

import java.util.List;

08

/**

 

09

 以泛型方法获取参数类型

10

 */

 

11

public class TypeArgumentsTest {

12

    public static void main(String[] args) throws Exception{

 

13

        //获取applyList方法对象

14

        Method method = TypeArgumentsTest.class.getMethod("applyList", List.class);

 

15

        //获取方法上泛型参数

16

        Type[] types=method.getGenericParameterTypes();

 

17

        ParameterizedType pType = (ParameterizedType) types[0];

18

        //获取原始类型

 

19

        System.out.println(pType.getRawType());

20

        //获取实际类型参数

 

21

        System.out.println(pType.getActualTypeArguments()[0]);

22

    }

 

23

    public static void applyList(List<Date> list){

24

    }

 

25

}

 





----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值