全国统一服务热线

177-7503-3043

新闻中心

当前位置:首页>新闻中心

Java基础学习泛型有什么用怎么用

只要了解了泛型的一般使用情况就能够解决多半的问题。所以,首先我们来了解一下什么是泛型、为什么要使用它以及应用方法。

什么是泛型?

试想一个简单的添加方法(method),如下:

long,float或double类型并不能当作输入传给这个方法。

如果从该方法中抽象出数据类型,就可以得到一个新的方式,如下。

在这里,是泛型参数(也称为类型变量),和给某一方法声明的参数一样。

给或传递的泛型参数的值,与方法参数相似,叫做类型参数。

现在考虑数据结构,简单起见,我们来想一想数组。我们能够创建一个任意类型的数组吗?不可以。我们只能创建一个整数数组、浮点数数组或者其他一种特定类型的数组。好了,忘掉所有编程语言里实现数组的方法,然后问一个问题:“我们是否可以从这个数据结构中抽象出一种数据类型?”

答案是肯定的。Java中的ArrayList就是做这件事的一种类。通过List=newArrayList<>();就能创建一个字符串数组,当整数作为类型参数时,它就是整数数组,其他的也类似。

虽然我们用ArrayList作为例子,但由于其复杂性,我们不会讨论他们具体是怎么实现的。我们会借鉴一个盒子并思考怎么把这个盒子做出来,而这个盒子就是某个特定类型的通用框架(aGenericboxfromaSpecificTypedbox)。

思考以下代码,将一个字符串放进特定字符串框架(SpecifizedStringBox)对象中,然后以此获得一个字符串。

现在,如果从该对象中抽取其数据类型“Type”,就得到一个由以下代码代表的通用框架(GenericBox,也就是泛型),而该框架可以使用String、Integer、Boolean等任意数据类型。

所以,使用泛型,就是要从某个方法(method)或者类(class)中,抽象出一种适用于任意类型的通用方法/类。

为什么要用泛型?

简单点的答案就是,通过泛型抽象数据类型后,你的代码可以重复使用并且易于维护。

泛型应用在什么地方?

看起来似乎通过重构已有特定类型的方法或框架,就能应用泛型。在处理数据结构和原始数据类型时,似乎还挺容易,但是我们总会在各不相同的类中建立大量的数据类型。泛型编程模式(GenericProgrammingParadigm)和面向对象编程(OOP)混合在一起时,就很难决定是否要使用泛型。理解在哪里应用泛型,问题就解决了一半。

本文就将带你了解一些典型的泛型用例,包括其使用场景,也可以让你在遇到同类型问题时能够合理应用泛型。

Java在JDK5.0中引用泛型的目的在于:

类型安全性(Typesafety):一旦使用类型参数后,在该方法或框架中就不存在其他的数据类型,同时也避免了类型转化的需求;

通用编程及参数的多态性。

C++的模版编程能帮我们实现通用编程及参数的多态性,根据数据的类型(预定义或用户定义的)转化同样的算法模型,达到复用同一个代码或程序的目的。在Java中也可以使用类似的方法。

现在来看一下几个常用的泛型用例。

用例1:泛型的级别用法是算法和数据类型

算法和数据结构并行,数据类型的微小变化可能会改变一个算法的复杂性。

数据结构中的数据有类型,用泛型将这种类型抽取出来,可以作为类型参数。而算法的输入参数也具有数据类型,同样,通过泛型可以将该类型从输入参数中抽象出来。因此,泛型适用于使用特定数据结构的任意一种算法。

不过事实上,泛型主要用于Java的集合API。

如果你自己写数据结构,那么一定试试利用泛型。除了Java的集合API,你也会在Guava、ApacheCommonCollection、FastUtils、JCtools和EclipseCollection里发现其他对泛型更好的应用。

用例2:数值输入框或者单个元素的容器

具备可通用类型的数据结构,可以称之为泛型框架(GenericsBoxes)。例如ArrayList、LinkedList等等这样的类就代表数据类型,同时为他们同类型的数据起着泛型框架的作用。

有时候,通用框架以单个元素而不是集合的形式出现。诸如Map映射中的输入,节点,数据对,以及其他代数数据类型,像是可选项,选择等等,它们只作为特定类型数据的依托(Holder)或封装器(wrapper)而已。

ThreadLocal和AtomicReference在适用于并发访问算法的单元素容器中,是非常好的例子。

类似的用法有时合理,而有一些则不太适用。一个盒子在早期确实可以容纳任何类型的物品,但现在会将其进行分类:这个盒子用来装玩具,而下一个盒子用来装笔,等等。

杯子是很好的例子,可以把它比做实时对象类型的依托物(Holder),它可以装茶、咖啡或者任何饮料。公交上可以坐男人和女人,如果让公交具备类型安全性且只允许女人上车,那么我们可以称之为女士公交。这种比喻可能有点欠妥,但它提出了商业用例,尤其是封装器或者依托物也具有应用泛型的可能。尝试询问业务的封装或依托是否有使用数据结构的倾向,如果有,那么使用泛型会更好。

用例类型3:抽象类型的泛型工具方法

泛型算法不一定总是和特定的数据结构或算法绑定在一起。有时,基于实际应用的满意度,它还可以应用在大多数抽象数据结构组中。

在Java中就有该Collections工具类。

查看以下方法,了解什么方法能适用:

CollectionFactoriesMethods,Empty/Singleton

emptyList,emptyMap,emptySet

singleton,singletonList,singletonMap

封装方法(Synchronized,UnModifiable,CheckedCollection):

synchronizedCollection,synchronizedSet,synchronizedMap

unmodifiableCollection,unmodifiableSet,unmodifiableList

checkedCollection,checkedList,checkedSet

还有一些泛型方法,可归为类:

1.更改列表中的元素顺序:reverse,rotate,shuffle,sort,swap;

2.更改列表内容:copy,fill,replaceAll;

3.在集合中寻找极值:较大值,较小值;

4.在列表中查找特定值:binarySearch,indexOfSubList,lastIndexOfSubList。

由于他们适用于列表中的任意类型,这些都是可复用的功能。我们会发现,大多数集合都适用泛型方法。

用例类型4:泛型方法用于类的分层并行结构中

Spring框架中的JpaRepository、CrudRepository都已使用泛型构建,创建、更新、查找、查找所有、删除等等,是适用于所有实体的泛型方法。

需要给每个实体创建一个并行数据访问对象(DAO)类时,会出现类的分层并行结构(parallelhierarchyofclasses)。不过DAO模式并不是其出现的情况。

如果为了提供更多可能的方法实例,我们可以通过将方法与对象解除联系的方式,来应用策略模式(StrategyPattern)处理业务问题,这时类的分层并行结构就会出现。

每当我们添加一个新类,就会增加一个并行的测试用例。如果需要工厂,我们就添加一个并行工厂类。类的分层并行结构出现在业务用例中。试想一辆新车,比如“大巴车”,把它添加到以下的车辆层级中时,可能还需要添加一个“大巴车司机”的类。


QQ咨询
在线咨询
在线报名
177-7503-3043
177-7503-3043
返回顶部