Java基础知识整理二(抽象类、接口…

 

11、Java中的抽象类、接口

抽象类必须使用abstract修饰符类修饰,抽象方法也是。抽象类中可以包含属性、方法(普通方法和抽象方法都可以)、构造器、初始化快、内部类、枚举类等。抽象类中的构造器不能用于创建实例,主要是用于被其子类调用。

接口修饰符可以是public或者省略。接口可以继承多个接口。接口中不嫩更有构造器和初始化块。接口里的属性必须是常量,方法只能是抽象的实例方法。接口中的成员迷人是public权限,可以省略权限修饰符,且只能指定为public。接口中的常量,系统会默认自动增加static和final修饰,系统中的抽象方法,会自动增加abstract修饰符。实现接口时,实现的方法修饰符必须是public,因为接口里的方法都是public的,而重写方法时不能缩小控制权限。

12、内部类、内部匿名类

内部类作为类的成员,和一般成员具有类似的性质。一般来说,内部类可以访问外部类类中的一些成员,不同的是在外部类内访问内部类的成员需要通过内部类的对象来访问。

非静态内部类对象必须寄存在外部类的对象中,而外部类的对象则不一定有非静态内部类对象寄存其中。简单的说,如果存在一个非静态内部类对象,则一定存在一个被他寄存的外部类对象,但外部类对象存在时,则不一定寄存了非静态内部类对象。因此外部类对象访问非静态内部类对象时,可能此时根部不存在非静态内部类对象,所以,需要通过对象昂来访问非静态内部类对象。Java不允许在非静态内部类中定义静态成员,否则或发生编译错误。(静态成员在类加载时就会加载,而非静态类内部类作为外部类的一个实例成员,此时还不一定加载,产生矛盾),同理,静态内部类实例成员不能访问外部类实例成员(静态内部类对象不是寄存在外部类对象里,而是寄存在外部类本身中。也就是说,当静态内部类的对象存在时,并不存在一个被他寄存的外部类对象,静态内部类的对象里只有外部类的类引用而没有外部类的对象引用)。静态内部类可以包含静态成员,也可以包含非静态成员。

在外部类以外创建一个非静态内部类对象,需要通过外部类的对象来调用其内部类的构造器。

匿名内部类:new 父类构造器(实参列表)|实现接口()

{

//类体

}

匿名内部类不能是抽象类,不能定义构造器,其必须继承一个父类或者实现一个接口,且单继承单实现,用来创建那种只需要使用一次的类。匿名内部类创建的同时会立即创建该类的一个实例。如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量。因为定义匿名内部类时会创建该类的一个实例,是持久化的,而局部变量是会即刻消失的,所以需要定义为final。

13、Java集合

Java的集合类主要由两个接口派生而出,Collection和Map,他们是集合类的根接口。Java集合体系大体上分为四种,Set、Queue、List和Map,其中Set表示无序、不可重复的集合,List代表有序可重复的集合,Queue代表一种队列集合的实现(从JDK1.5增加的),Map代表具有映射关系的集合(Map的Key不可重复)。其中Set、Queue和List继承了Collection接口,HashMap等实现了Map接口。

Collection接口和Iterator接口:Collection接口是List、Set、Queue接口的父接口,其中包含了一些操作集合的最基本的方法,想了解有哪些方法可以参考Java API文档;Iterator接口也是Java集合框架的成员,主要用于迭代访问、遍历Collection结合中的元素。下面介绍下常用的接口及其主要的实现类。

Set接口:Set结合不允许包含相同的元素,要求其中两个对象用equals()方法比较后返回false。

HashSet:HashSet是Set接口的典型实现类,大多数使用Set集合时就是使用这个实现类,HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找功能。HashSet具有以下几个特点:a、不能保证元素的排列顺序,顺序有可能发生变化;b、HashSet不是同步的,非线程安全;c、Hashset的元素可以是null。HashSet放入元素时,会调用该对象的hashCode()方法来得到该对象的HashCode值,然后根据这个值来决定该对象在HashSet中的存储位置。原则就是,HashSet在判断两个元素相等的标准是两个对象通过equals方法比较相等,且两个对象的hashCode()返回值相等。

TreeSet:TreeSet是Set接口子接口SortedSet的实现类。TreeSet可以确保集合元素处于排序状态,与HashSet不同的是,TreeSet采用红黑树的数据机构对元素进行排序。当把元素放入TreeSet中时,TreeSet会调用该对象的compareTo(Object obj)方法与集合中的其他元素进行比较,从而确定其存储位置,所以TreeSet中应该存贮同一个类的对象。对于TreeSet而言,他判断两个对象不相等的标准是,两个对象通过equals方法比较返回false,通过compareTo()方法比较返回0。

List接口:List接口代表一个有序集合,集合中的每一个元素都有其对应的顺序索引。List集合允许重复的元素,其默认索引顺序为0、1、2。List判断两个元素相等的标注是判断equals方法返回true。对于List接口,还提供了一个ListIterator接口用来操作List。其主要实现类有ArrayList和Vector。

ArrayList和Vector都是基于数组实现的List类,都封装了一个动态再分配的Object[]数组。每个ArrayList或Vector对象都有一个capacity属性,表示其Object[]数组长度,其默认值是10.其显著区别是,ArrayList是线程不安全的,Vector是线程安全的,所以Vector较ArrayList性能要低。

Queue接口:Queue接口用于模拟队列这种数据结构,通常是先进先出,不允许随即访问队列中的元素。其典型实现类是LinkedList。其内部是以链表的形式来保存集合中的元素的。其访问元素时性能较ArrayList和Vector差一些,但在插入、删除元素时性能非常出色。总之,ArrayList、Vector和LinkedList比较而言,Vector是线程安全的,在各方面性能都稍差一点。在实际应用中,一般常用ArrayList、如果需要经常插入删除元素,则应使用Linkedlist,其速度比其他快很多、如果要求线程同步,则可以使用Vector。

Map接口:Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,分别是Key和Value,Map的Key不允许重复,即通过equals方法比较后返回false。Map的Key集类似于Set而Value集类似于List。其主要的实现类有HaspMap和Hashtable。他们之间的关系完全类似于ArrayList和Vector:Hashtable是一个线程安全的Map实现,HasnMap不是,所以HashMap的性能较高点;Hashtable不允许使用null值作为key和value,HashMap允许有一个Key是null,允许多个Value是null。HashMap、HashTable也不能保证其key-value对的顺序。他们判断两个key相等的标准也是两个key通过比较equals返回true,且hashCode值相等。

另外HasnTable还有一个很有用的子类Properties。他可以吧Map对象和属性文件关联起来,将Map对象中的键值对写入属性文件中,或从属性文件中读取键值对到Map对象中。其中属性名和属性值只能是字符串类型,Properties对象中key、value也只能是String类型的。

Collections集合:Java提供了一个操作集合的工具类,Collections。该工具类提供了大量方法对集合中的元素进行排序、查询和修改,还实现了将集合对象设置为不可变、对集合对象实现同步控制等方法。其功能非常强大,感兴趣可以参照API文档。

14、Java泛型

设计原则:Java泛型设计的原则是如果在编译时没有产生unchecked未经检查的转换警告,则程序运行时不会引发ClassCastException异常。

泛型继承:可以为任何类增加泛型声明,在泛型类或接口里面,类型形参可以当成普通类型使用。当创建了带泛型声明的接口或父类之后,可以为该接口创建实现类,或者从该父类来派生子类,但值得指出的是,当使用这些接口、父类时,不能再包含类型形参,可以不带泛型参数或者传入具体的类型参数。如果不带类型形参,则在实现类或者子类中,会把类似于Apple<T>中的T当做是Object类型。

并不存在真正泛型类:实际上,泛型对其所有可能的类型参数都具有同样的行为,从而可以把相同的类当成不同的类来处理。与此完全一致的是,类的静态变量和方法也在所有的实力间共享,所以静态方法、静态初始化或者静态变量的声明和初始化中不允许使用类型形参。系统中不会真正的生成泛型类,所以instanceof运算符后不能使用泛型类,例如Collection cs=new ArrayList<String>; if(cs instanceof List<String>)(...)是错误的。

类型通配符:注意,List<String>不是List<Object>的子类。在定义方法的形参时,如果不知道实际使用时要传入什么类型的参数,则可以使用类型通配符。但是使用类型通配符,如List<?>仅表示他是所有其他泛型List的父类,然而由于不知道他到底是什么类型的,多以无法往其中添加元素,否则会引起编译错误。类型通配符可以设定上限或者设定下限,如public void copy(Collection<T> dest,List<? Extends T> src)表示实际传入的src参数类型必须是T类型或者是其子类型,这样才能顺利的加入。或者public void copy(Collection<? super T> dest,Collection<T> src),表示dest参数的类型必须是src参数类型的或者其子类。这两种方式虽然意思差不多,但还是存在一定的区别的,因为在调用该方法时,系统会根据实际T来确认另外一个参数的数据类型,在实际使用时还是要注意的。

泛型方法:假如要实现这样一个方法,该方法负责把一个Object数组的所有元素添加到一个Collection集合中去,如果如下定义:public void add(Object[] a,Collection<Object> c),定义时没有问题的,如果此时我将一个String数组添加到Collection中去,按说应该也是可以的,但实际不行,因为Collection<String>不是Collection<Object>类型的子类,所以实际这样用时会产生编译错误。那该怎么办呢?使用通配符显然也是不行的,因为不能把一个对象放进一个未知类型的集合中去。这里我们可以使用泛型方法。其定义格式为【修饰符 <T,S> 返回值类型 方法名(形参列表){...}】。具体使用和普通类型一样,这里就不举例了。

通配符使用的好有时和泛型方法可以达到类似的效果。如果一个泛型方法中的类型形参唯一效果就是在不同的调入点传入不同的实际类型,则应该使用通配符,通配符的设计就是用来支持灵活的子类化的。泛型方法允许类型形参被用来表示方法的一个或多个参数之间的类型依赖关系,或者方法返回值与参数之间的依赖关系。

Java不允许创建泛型数组,即数组类型不能包含类型变量或者类型形参,除非是无上限的类型通配符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位和目标分类。首先检测图像目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标和右下角坐标),一个置信度分数(Confidence Score),表示边界框是否包含检测对象的概率和各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stage和One stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第个阶段是分类和位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类和定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列和RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为极大值抑制,作用是从众多预测边界框挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选值最大的框 遍历其余的框,如果和当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框和真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测Precision和Recall的概念。 首先我们设置置信度阈值(Confidence Threshold)和IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 Precision和Recall的概念如下图所示: Precision表示TP与预测边界框数量的比值 Recall表示TP与真实边界框数量的比值 改变不同的置信度阈值,可以获得多组Precision和Recall,Recall放X轴,Precision放Y轴,可以画出一个Precision-Recall曲线,简称P-R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值