Day13——泛型

1.泛型

1.1 介绍

所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值或参数的类型。这个类型参数将在使用时(例如,继承或实现这个接口、创建对象或调用方法时)确定(即传入实际的类型参数,也称为类型实参)。

@Testpublic void test1(){//类型推断,JDK7的新特性ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);}

1.2 在集合中使用泛型之前可能存在的问题

  1. 类型不安全。因为add()的参数是Object类型,意味着任何类型的对象都可以添加成功。
  2. 需要使用强制类型转换操作,可能导致ClassCastException异常。

1.3 使用说明

集合框架在声明接口和其实现类时,使用了泛型(JDK5.0),在实例化集合对象时:

  1. 如果没有使用泛型,则认为操作的是Object类型的数据。
  2. 如果使用了泛型,则需要指明泛型的具体类型。一旦指明了泛型的具体类型,则在集合的相关方法中,凡是使用泛型参数的位置,都指定为具体的参数类型。

1.3.1 集合中使用泛型

@Testpublic void test2() {HashMap<String, Integer> map = new HashMap<>();map.put("张三", 89);map.put("李四", 98);var entrySet = map.entrySet();var iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry<String, Integer> entry = iterator.next();String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + "--->" + value);}}

1.3.2 比较器中使用泛型

package p164;import java.util.ArrayList;
import java.util.Iterator;
import java.util.function.Predicate;public class ArrayListTest {public static void main(String[] args) {//1.创建一个ArrayList集合对象并指定泛型为<Integer>ArrayList<Integer> list = new ArrayList<>();//2.添加5个[0,100)以内的随机整数到集合中list.add((int) (Math.random()*100-1));list.add((int) (Math.random()*100-1));list.add((int) (Math.random()*100-1));list.add((int) (Math.random()*100-1));list.add((int) (Math.random()*100-1));//3.使用foreach遍历输出5个整数for (Integer i :list) {System.out.println(i);}//4.使用集合的removeIf方法删除偶数,为Predicate接口指定泛型<Integer>list.removeIf(new Predicate<Integer>() {@Overridepublic boolean test(Integer value) {return value % 2 == 0;}});System.out.println("-----");//5.再使用Iterator迭代器输出剩下的元素,为Iterator接口指定泛型<Integer>Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()){Integer i = iterator.next();System.out.println(i);}}
}

1.4 自定义泛型类、接口

当我们在类或接口中定义某个成员时,该成员的相关类型是不确定的,而这个类型需要在使用这个类或接口时才可以确定,那么我们可以使用泛型类、泛型接口。

1.4.1 格式

class A<T>{}
interface B<T1,T2>{}

1.4.2 使用说明

  1. 我们在声明完自定义泛型类以后,可以在类的内部(比如:属性、方法、构造器中)使用类的泛型。
  2. 我们在创建自定义泛型类的对象时,可以指明泛型参数类型。一旦指明,内部凡是使用类的泛型参数的位置,都具体化为指定的类的泛型类型。
  3. 如果在创建自定义泛型类的对象时,没有指明泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照 Object 处理,但不等价于Object。
  4. 泛型的指定中必须使用引用数据类型。不能使用基本数据类型,此时只能使用包装类替换。
  5. 除创建泛型类对象外,子类继承泛型类时、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数。如果我们在给泛型类提供子类时,子类也不确定泛型的类型,则可以继续使用泛型参数。我们还可以在现有的父类的泛型参数的基础上,新增泛型参数。

1.4.3 注意点

  1. 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>。
  2. JDK7.0 开始,泛型的简化操作:ArrayList flist = new ArrayList<>();
  3. 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
  4. 不能使用 new E[]。但是可以:E[] elements = (E[])new Object[capacity];——>参考:ArrayList 源码中声明:Object[] elementData,而非泛型参数类型数组。
  5. 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,但不可以在静态方法中使用类的泛型。
  6. 异常类不能是带泛型的。

1.5 自定义泛型方法

1.5.1 格式

//通常在形参列表或返回值类型的位置会出现泛型参数T
权限修饰符 <T> 返回值类型 方法名(形参列表){}
public <E> E method(E e){return null;
}

1.5.2 说明

  1. 声明泛型方法时,一定要添加泛型参数。
  2. 泛型参数在方法调用时,指明其具体的类型。
  3. 泛型方法可以根据需要声明为static。
  4. 泛型方法所属的类是否是一个泛型类,都可以。

1.6 通配符?

当我们声明一个变量/形参时,这个变量/形参的类型是一个泛型类或泛型接口,例如:Comparator 类型,但是我们仍然无法确定这个泛型类或泛型接口的类型变量的具体类型,此时我们考虑使用类型通配符 ? 。
使用类型通配符:?比如:List<?>,Map<?,?>,List<?>是 List、List等各种泛型 List 的父类。

1.6.1 写操作

将任意元素加入到其中不是类型安全的:
Collection<?> c = new ArrayList();
c.add(new Object()); // 编译时错误
因为我们不知道 c 的元素类型,我们不能向其中添加对象。add 方法有类型参数 E 作为集合的元素类型。我们传给 add 的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。唯一可以插入的元素是 null,因为它是所有引用类型的默认值。

1.6.2 读操作

读取 List<?>的对象 list 中的元素时,永远是安全的,因为不管 list 的真实类型是什么,它包含的都是 Object。

1.6.3 有限制的通配符

  1. <?>
    • 允许所有泛型的引用调用。
  2. 通配符指定上限:<? extends 类/接口 >
    • 使用时指定的类型必须是继承某个类,或者实现某个接口,即<= 。
  3. 通配符指定下限:<? super 类/接口 >
    • 使用时指定的类型必须是操作的类或接口,或者是操作的类的父类或接口的父接口,即>=。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/196338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你知道 n 进制如何转化为 m 进制吗?

更好的阅读体验&#xff0c;请点击 进制转换 | YinKais Blog 程序介绍&#xff1a;n 进制数转换器 这个简单的C程序是一个 n 进制数转换器&#xff0c;可以将一个给定的 n 进制数按照用户指定的进制进行转换。用户需要提供三个输入&#xff1a;原始进制&#xff0c;待转换的数…

目标检测中的损失函数:IOU_Loss、GIOU_Loss、DIOU_Loss和CIOU_Loss

文章目录 前言1.IOU_Loss&#xff08;Intersection over Union Loss&#xff09;2.GIOU_Loss&#xff08;Generalized Intersection over Union Loss&#xff09;3.DIOU_Loss&#xff08;Distance Intersection over Union Loss&#xff09;4.CIOU_Loss&#xff08;Complete In…

行云创新:与德国汽车业交流Catena-X数据空间技术有感

近日&#xff0c;行云创新CEO马洪喜先生受深圳高新投、Plug&Play邀请参加Catena-X技术研讨交流会&#xff0c;与西门子全球汽车生态系统总监Claus CREMERS&#xff0c;大众汽车全球数字化生产及流程负责人Frank GOELLER&#xff0c;宝马全球数字化政策负责人Sebastian SCHL…

Gensim训练中文词向量实战

引言 实现文本匹配模型时经常需要预训练好的中文词/字向量&#xff0c;今天通过gensim和中文维基百科数据训练一个中文字向量。 安装相关包 首先要安装所需的几个包&#xff1a; zhconv 1.4.3 gensim 4.3.2由于中文维基百科是繁体字&#xff0c;需要用zhconv转换为简体&…

【国际会议】2024年材料科学与机械应用发展国际会议(ICMSMAD 2024)

2024年材料科学与机械应用发展国际会议(ICMSMAD 2024) 2024 International Conference on Materials Science and Mechanical Application Development(ICMSMAD 2024) 一、【会议简介】 ​2024年材料科学与机械应用发展国际会议(ICMSMAD 2024)即将在美丽的中国成都盛大召开。这…

贪心法之柠檬水找零

题目: 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。 你必须给每个顾客正确找零&am…

使用gdb调试正在运行的程序

写一个一秒打印一个数的c程序&#xff0c;并编译运行。 #include<unistd.h> #include<stdio.h> int main(int argc,char **argv){int i0;while(1){sleep(1);i;printf("%d\n",i);}return 0; }vim loop.c gcc loop.c -o loop ./loop 查看该进程的进程号。…

《数据库系统概论》学习笔记——王珊 萨师煊

第一章 绪论 一、数据库系统概述 1.数据库的4个基本概念 &#xff08;1&#xff09;数据 描述事物的符号记录称为数据 &#xff08;2&#xff09;数据库 存放数据的仓库 &#xff08;3&#xff09;数据库管理系统 主要功能&#xff1a; &#xff08;1&#xff09;数据定…

APP逆向工具环境安装

环境安装及配置&#xff1a; 1.JDK安装及配置链接&#xff1a;https://pan.baidu.com/s/146I4vDJdz8YeR0OEqLS8xw 提取码&#xff1a;7h00 2.SDK环境配置链接&#xff1a;https://pan.baidu.com/s/1A8rwqyw8Nn7p93Axqpll3A 提取码&#xff1a;cwv43.NDK环境配置链接&#xff1…

【Spark基础】-- 理解 Spark shuffle

目录 前言 1、什么是 Spark shuffle? 2、Spark 的三种 shuffle 实现 3、参考 前言 以前,Spark 有3种不同类型的 shuffle 实现。每种实现方式都有他们自己的优缺点。在我们理解 Spark shuffle 之前,需要先熟悉 Spark 的 execution model 和一些基础概念,如:MapReduce、…

【问题】C++ libcurl实现PUT时阻塞问题

解决方案 将 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);换成 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); 原因 在项目中对方要求使用PUT来发送控制指令&#xff0c;于是直接使用Libcurl来实现。原本是一个非常简单的事情&#xff0c;确怎么都没发…

SpringBoot:SpringMVC(上)

文章目录 前言一、SpringMVC是什么&#xff1f;1.1 MVC的定义&#xff1a;1.2 MVC 和 Spring MVC 的关系 二、Spring MVC 创建和连接2.1创建springmvc2.2接下来&#xff0c;创建⼀个 UserController 类&#xff0c;实现⽤户到 Spring 程序的互联互通&#xff0c;具体实现代码如…

MYSQL练题笔记-聚合函数-即时食物配送

我做完上一道题&#xff0c;决定总结一下了&#xff0c;因为现在还是没有一个我认为好的思路去构造语句&#xff0c;这里开始试一试新的思路。果然想要好一点的时候&#xff0c;总是像便秘一下&#xff0c;真的想拉&#xff0c;但是真的难拉啊 一、题目相关内容 1&#xff09…

科普关于msvcp140.dll文件是什么内容,解决msvcp140.dll丢失的修复方法

在使用电脑时出现了关于msvcp140.dll丢失的问题&#xff0c;这是什么情况&#xff0c;出现这样的问题通常都会导致电脑中的一些软件不能使用&#xff0c;那么都有什么办法能够解决msvcp140.dll丢失的问题呢&#xff1f;今天就给大家科普一些关于msvcp140.dll文件是什么的内容&a…

小程序长按识别二维码

小程序开发中要实现长按识别二维码的功能很简单&#xff0c;只需要在image标签里添加如下属性即可&#xff1a; 小程序版本&#xff1a; show-menu-by-longpress"{{true}}" uniapp版本&#xff1a; :show-menu-by-longpress"true" 举例&#xff1a; …

小红书种草笔记多少钱?给大家揭秘

小红书&#xff0c;一个以生活方式分享为主题的社交电商平台&#xff0c;吸引了众多年轻用户。种草笔记&#xff0c;是指用户在小红书上分享的关于某一产品或服务的使用体验、心得感悟&#xff0c;通过图文并茂的形式&#xff0c;激发其他用户的好奇心和购买欲望&#xff0c;从…

资深老鸟整理,高级测试工程师应具备的能力...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、业务熟悉 熟悉…

在国内Facebook广告怎么解决充值渠道问题?

怎么解决Facebook预充值跑广告营销的付款方式问题呢&#xff1f; Facebook跑广告是很多做出口营销的公司或团队喜欢的平台之一&#xff0c;那就避免不了需要支付给Facebook平台广告费用了&#xff0c;那到底用什么方式去充值到FB号上去解决呢&#xff1f;FB预充值有什么咔可以…

操作系统·设备管理

I/O系统是计算机系统的重要组成部分&#xff0c;是OS中最复杂且与硬件密切相关的部分 I/O系统的基本任务是完成用户提出的I/O请求&#xff0c;提高I/O速率以及改善I/O设备的利用率&#xff0c;方便高层进程对IO设备的使用 I/O系统包括用于实现信息输入、输出和存储功能的设备和…

stm32L071KB单片机字节对齐问题

字节对齐问题由来很关键 字节对齐问题由来 字节对齐问题由来 在移植同事代码的时候发现到一个赋值变量的地方就会出现死机&#xff0c;进入hardfault,怎么也找不不到原因&#xff0c;最后没办法去了github https://github.com/armink/CmBacktrace/blob/master/README_ZH.md Cm…