泛型的详解
泛型的理解和好处
首先我们先来看看泛型的好处
1)编译时,检查添加元素的类型,提高了安全性
2)减少了类型转换的次数,提高效率[说明]
不使用泛型 Dog -> Object -> Dog//放入到ArrayList 会先转成Object,在取出时,还需要转换成Dog使用泛型 Dog-> Dog -> Dog//放入时,和取出时,不需要类型转换,提高效率
3)不再提示编译警告
代码演示:
注意:
1.当我们在集合的后面指定了泛型,那么表示存放到集合中的元素的类型是dog类型
2.如果我们加入的类型不是dog那么编译器会直接报错
3.我们在遍历的时候,可以直接取出dog的类型而不是Object
package idea.chapter15.generic.improve;import java.util.ArrayList;@SuppressWarnings({"all"})
public class Generic02 {public static void main(String[] args) {//使用传统的方法来解决===> 使用泛型//1. 当我们 ArrayList<Dog> 表示存放到 ArrayList 集合中的元素是Dog类型//2. 如果编译器发现添加的类型,不满足要求,就会报错//3. 在遍历的时候,可以直接取出 Dog 类型而不是 Object//4. public class ArrayList<E> {} E称为泛型,那么 Dog->EArrayList<Dog> arrayList = new ArrayList<Dog>();arrayList.add(new Dog("旺财", 10));arrayList.add(new Dog("发财", 1));arrayList.add(new Dog("小黄", 5));//假如我们,不小心,添加了一只猫,就会直接报错//arrayList.add(new Cat("招财猫", 8));System.out.println("===使用泛型====");for (Dog dog : arrayList) {System.out.println(dog.getName() + "-" + dog.getAge());}}
}/*
1.请编写程序,在ArrayList 中,添加3个Dog对象
2.Dog对象含有name 和 age, 并输出name 和 age (要求使用getXxx())
3.使用泛型来完成代码*/
class Dog {private String name;private int age;public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}class Cat { //Cat类private String name;private int age;public Cat(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
泛型的介绍
理解:泛(广泛)型(类型)=> Integer,String,Dog
1)泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题
2)在类声明或实例化时只要指定好需要的具体的类型即可。
3)Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产ClassCastException异常。同时,代码更加简洁、健壮
4)泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
代码演示:
注意:
泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,
或者是某个方法的返回值的类型,或者是参数类型
class Person <E> 红色标注的这一块就是泛型,在代码中我们可以看到,我们在类的后面加入了<E>就表示该一个类型,后面根据我们传入的不同的对象,比如我们传入的是一个String,那么E就是String类型的,传入的是一个Integer 那么E 就是一个Integer
package idea.chapter15.generic;public class Generic03 {public static void main(String[] args) {//注意,特别强调: E具体的数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型Person<String> person = new Person<String>("jack");person.show(); //String/*你可以这样理解,上面的Person类class Person {String s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(String s) {//E也可以是参数类型this.s = s;}public String f() {//返回类型使用Ereturn s;}}*/Person<Integer> person2 = new Person<Integer>(100);person2.show();//Integer/*class Person {Integer s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(Integer s) {//E也可以是参数类型this.s = s;}public Integer f() {//返回类型使用Ereturn s;}}*/}
}//泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,
// 或者是某个方法的返回值的类型,或者是参数类型class Person<E> {E s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(E s) {//E也可以是参数类型this.s = s;}public E f() {//返回类型使用Ereturn s;}public void show() {System.out.println(s.getClass());//显示s的运行类型}
}
泛型的语法
泛型的声明
interface接口<T>和class 类<K,V>
//比如:List,ArrayList
说明: 1)其中,T,K,V不代表值,而是表示类型。
2)任意字母都可以。常用T表示,是Type的缩写
泛型的实例化:
要在类名后面指定类型参数的值(类型)
-
List<String> strList =new ArrayList<String>(); [举例说明]
-
Iterator<Customer> iterator = customers.iterator();
泛型课堂练习
代码演示:
package idea.chapter15.generic;import java.util.*;/*
练习:
1. 创建3个学生对象
2. 放入到HashMap中,要求Key是String name,Value就是 学生对象
3.使用两种方式遍历*/
@SuppressWarnings({"all"})
public class GenericExercise {public static void main(String[] args) {HashSet<Student> students = new HashSet<>();students.add(new Student("jack", 12));students.add(new Student("tom", 10));students.add(new Student("smith", 1));// //使用增强for遍历
// System.out.println("使用增强for的方式");
// for (Student student : students) {
// System.out.println(student);
// }
//
// //使用迭代器
// System.out.println("使用迭代器的方式");
// Iterator<Student> iterator = students.iterator();
// while (iterator.hasNext()) {
// Student next = iterator.next();
// System.out.println(next);
// }//使用HashMapHashMap<String, Student> hashMap = new HashMap<>();hashMap.put("jack", new Student("jack", 1));hashMap.put("tom", new Student("tom", 11));hashMap.put("mary", new Student("mary", 111));//使用增强forSet<String> strings = hashMap.keySet();for (String string : strings) {System.out.println(string + "-" + hashMap.get(string));}//使用迭代器System.out.println("\n使用迭代器的方式");Set<Map.Entry<String, Student>> entries = hashMap.entrySet();Iterator<Map.Entry<String, Student>> iterator = entries.iterator();while (iterator.hasNext()) {//此时的next就是一个EntryMap.Entry<String, Student> next = iterator.next();System.out.println(next.getKey() + "-" + next.getValue());}}
}class Student {private String name;private int id;public Student(String name, int id) {this.name = name;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", id=" + id +'}';}
}
泛型使用的注意事项和细节
1.interface List<T>0,public class HashSet<E>{}..等等,说明:T,E只能是引用类型
2.在给泛型指定具体类型后,可以传入该类型或者其子类类型
3.泛型使用形式
List<Integer> list1=new ArrayList<Integer>{}; List<Integer>list2=new ArrayList<>);
3.如果我们这样写 List list3=new ArrayList0;默认给它的 泛型是[<E> E就是Object]即:
代码演示:
package idea.chapter15.generic;import java.util.ArrayList;
import java.util.List;/*** 讲解泛型的注意事项和使用细节*/
@SuppressWarnings({"all"})
public class GenericDetail {public static void main(String[] args) {//1.给泛型指向数据类型是,要求是引用类型,不能是基本数据类型List<Integer> list = new ArrayList<Integer>(); //OK//List<int> list2 = new ArrayList<int>();//错误//2. 说明//因为 E 指定了 A 类型, 构造器传入了 new A()//在给泛型指定具体类型后,可以传入该类型或者其子类类型Pig<A> aPig = new Pig<A>(new A());aPig.f();Pig<A> aPig2 = new Pig<A>(new B());aPig2.f();//3. 泛型的使用形式ArrayList<Integer> list1 = new ArrayList<Integer>();List<Integer> list2 = new ArrayList<Integer>();//在实际开发中,我们往往简写//编译器会进行类型推断, 老师推荐使用下面写法ArrayList<Integer> list3 = new ArrayList<>();List<Integer> list4 = new ArrayList<>();ArrayList<Pig> pigs = new ArrayList<>();//4. 如果是这样写 泛型默认是 ObjectArrayList arrayList = new ArrayList();//等价 ArrayList<Object> arrayList = new ArrayList<Object>();/*public boolean add(Object e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}*/Tiger tiger = new Tiger();//如果什么都不写,默认是Object,也就是下面的这种方式/*class Tiger {//类Object e;public Tiger() {}public Tiger(Object e) {this.e = e;}}*/}
}class Tiger<E> {//类E e;public Tiger() {}public Tiger(E e) {this.e = e;}
}class A {
}class B extends A {
}class Pig<E> {//E e;public Pig(E e) {this.e = e;}public void f() {System.out.println(e.getClass()); //运行类型}
}
泛型练习2
代码演示:
package idea.chapter15.generic;import java.util.ArrayList;
import java.util.Comparator;/*
泛型课堂练习题
定义Employee类
1)该类包含:private成员变量name,sal,birthday,其中birthday为MyDate类的对象;
2)为每一个属性定义getter,setter方法;
3)重写 toString 方法输出 name,sal,birthday
4) MyDate类包含:private成员变量month,day.year;并为每一个属性定义getter setter 方法;
5)创建该类的3个对象,并把这些对象放入ArrayList集合中(ArrayList需使用泛型来定义),对集合中的元素进行排序,并遍历输出:
排序方式:调用ArrayList的sort 方法,传入 Comparator对象[使用泛型],先按照name排序,如果name相同,则按生日日期的先后排序。 【即:定制排序】
有一定难度15min,比较经典 泛型使用案例*/
@SuppressWarnings({"all"})
public class GenericExercise02 {public static void main(String[] args) {ArrayList<Employee> employees = new ArrayList<>();employees.add(new Employee("jack", 200, new MyDate(2001, 1, 1)));employees.add(new Employee("tom", 100, new MyDate(2003, 3, 2)));employees.add(new Employee("tom", 300, new MyDate(2002, 5, 3)));employees.sort(new Comparator<Employee>() {@Overridepublic int compare(Employee o1, Employee o2) {//根据要求,如果名字相同我们按照出生日期比较,如果名字不相同就按照名字比较if (o1.getName().equals(o2.getName())) {return o1.getBirthday().getYear() - o2.getBirthday().getYear();} else//还可以继续增加逻辑,比如出生年份相同就按照月份比较return o1.getName().equals(o2.getName()) ? 1 : -1;}});System.out.println(employees);}
}class Employee implements Comparator {private String name;private double sal;private MyDate birthday;public Employee(String name, double sal, MyDate birthday) {this.name = name;this.sal = sal;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "\nEmployee{" +"name='" + name + '\'' +", sal=" + sal +", birthday=" + birthday +'}';}@Overridepublic int compare(Object o1, Object o2) {return 0;}
}class MyDate {private int year;private int month;private int day;public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}@Overridepublic String toString() {return "MyDate{" +"year=" + year +", month=" + month +", day=" + day +'}';}
}
相关文章:
泛型的详解
泛型的理解和好处 首先我们先来看看泛型的好处 1)编译时,检查添加元素的类型,提高了安全性 2)减少了类型转换的次数,提高效率[说明] 不使用泛型 Dog -> Object -> Dog//放入到ArrayList 会先转成Object,在取出时&#x…...

用科技创造未来!流辰信息技术助您实现高效办公
随着社会的迅猛发展,科技的力量无处不见。它正在悄悄地改变整个社会,让人类变得进步和文明,让生活变得便捷和高效。在办公自动化强劲发展的今天,流辰信息技术让通信业、电网、汽车、物流等领域的企业实现了高效办公,数…...
基于R语言APSIM模型
随着数字农业和智慧农业的发展,基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。 APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物…...

块状链表实现BigString大字符串操作(golang)
前言 块状链表是介于链表和数组之间的数据结构,能够在 O ( n ) O(\sqrt{n}) O(n )时间内完成插入、删除、访问操作。 数据结构如图所示。假设最大容量为 n n n, 则它有一个长度为 s n s\sqrt{n} sn 的链表。链表中每个结点是一个长度为 2 n 2 \times \sqrt{…...
项目问题记录(持续更新)
1.在 yarn install的时候报 error achrinza/node-ipc9.2.2: The engine "node" is incompatible with this module. Expected version "8 || 10 || 12 || 14 || 16 || 17". Got "20.1.0" error Found incompatible module.需要执行 yarn config…...

Linux的进程
目录 一、进程占用的内存资源 二、进程的系统环境 三、进程一直在切换 四、父进程和子进程 五、进程状态 六、查看进程 1.ps -ef 列出所有进程 2.ps -lax 列出所有进程 3.ps aux列出所有进程 4.树形列出所有进程 七、作业(用来查看管理进程) …...

与其焦虑被 AI 取代或猜测前端是否已死, 不如看看 vertical-align 扎实你的基础!!!
与其焦虑被 AI 取代或猜测前端是否已死, 不如看看 vertical-align 扎实你的基础!!! vertical-align 设置 display 值为 inline, inline-block 和 table-cell 的元素竖直对齐方式. 从 line-height: normal 究竟是多高说起 我们先来看一段代码, 分析一下为什么第二行的行高, 也就…...
路由、交换机、集线器、DNS服务器、广域网/局域网、端口、MTU
前言:网络名词术语解析(自行阅读扫盲),推荐大家去读户根勤的《网络是怎样连接的》 路由(route): 数据包从源地址到目的地址所经过的路径,由一系列路由节点组成。某个路由节点为数据包选择投递方向的选路过程。 路由器工作原理 路…...

在全志V851S开发板上进行屏幕触摸适配
1.修改屏幕驱动 从ft6236 (删掉,不要保留),改为下面的 路径:/home/wells/tina-v853-open/tina-v853-open/device/config/chips/v851s/configs/lizard/board.dts(注意路径,要设置为自己的实际路…...
字符串拷贝时的内存重叠问题
字符串拷贝时的内存重叠问题 1.什么是内存重叠 拷贝的目的地址在源地址的范围内,有重叠。 如在写程序的过程中,我们用到的strcpy这个拷贝函数,在这个函数中我们定义一个目的地址,一个源地址,在拷贝的过程中如果内存重…...

告别PPT手残党!这6款AI神器,让你秒变PPT王者!
如果你是一个PPT手残党,每每制作PPT总是让你焦头烂额,那么你一定需要这篇幽默拉风的推广文案! 我向你保证,这篇文案将帮助你发现6款AI自动生成PPT的神器,让你告别PPT手残党的身份,成为一名PPT王者。 无论…...
JVM配置与优化
参考: JVM内存分区及作用(JDK8) https://blog.csdn.net/BigBug_500/article/details/104734957 java 进程占用系统内存过高分析 https://blog.csdn.net/fxh13579/article/details/104754340 Java之jvm和线程的内存 https://blog.csdn.ne…...

电力系统储能调峰、调频模型研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

C++基础之类、对象一(类的定义,作用域、this指针)
目录 面向对象的编程 类的引入 简介 类的定义 简介 访问限定符 命名规则 封装 简介 类的作用域 类的大小及存储模型 this指针 简介 面向对象的编程 C与C语言不同,C是面向对象的编程,那么什么是面向对象的编程呢? C语言编程,规定…...

javaScript---设计模式-封装与对象
目录 1、封装对象时的设计模式 2、基本结构与应用示例 2.1 工厂模式 2.2 建造者模式 2.3 单例模式 封装的目的:①定义变量不会污染外部;②能作为一个模块调用;③遵循开闭原则。 好的封装(不可见、留接口):①…...

【消息中间件】kafka高性能设计之内存池
文章目录 前言实现创建内存池分配内存释放内存 总结 前言 Kafka的内存池是一个用于管理内存分配的缓存区域。它通过在内存上保留一块固定大小的内存池,用于分配消息缓存、批处理缓存等对象,以减少频繁调用内存分配函数的开销。 Kafka内存池的实现利用了…...
创建型模式——单例(singleton)
1. 模式说明 单例模式保证类只有一个实例;创建一个对象,当你创建第二个对象的时候,此时你获取到的是已经创建过的对象,而不是一个新的对象; 1.1 使用场景 共享资源的访问权限;任务的管理类;数…...

算法:迷宫问题
描述 定义一个二维数组 N*M ,如 5 5 数组下所示: int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或…...

聊聊并发编程的12种业务场景
前言 并发编程是一项非常重要的技术,无论在面试,还是工作中出现的频率非常高。 并发编程说白了就是多线程编程,但多线程一定比单线程效率更高? 答:不一定,要看具体业务场景。 毕竟如果使用了多线程&…...

MySQL执行顺序
MySQL执行顺序 MySQL语句的执行顺序也是在面试过程中经常问到的问题,并且熟悉执行顺序也有助于SQL语句的编写。 SELECT FROM JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT执行顺序如下: FROM ON JOIN WHERE GROUP BY # (开始使用别名) SUM # SUM等…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...