Java语言程序设计——篇十一(1)

在这里插入图片描述

     🌿🌿🌿跟随博主脚步,从这里开始→博主主页🌿🌿🌿

  • 欢迎大家:这里是CSDN,我的学习笔记、总结知识的地方,喜欢的话请三连,有问题可以私信🌳🌳🌳
    您的点赞、关注、收藏、评论、私信是我最大的支持与鼓舞!!!🌻🌻🌻

泛型

  • 泛型类型
    • 实战演练
    • 实战演练
  • 泛型方法
    • 实战演练
  • 通配符(?)的使用
    • 实战演练
  • 有界类型参数
    • 实战演练
  • 继承泛型类与实现泛型接口
      • 🐱综合练习

泛型类型

  • 泛型其实质就是将数据的类型参数化,通过为类、接口及方法设置类型参数来定义泛型。
  • 泛型使一个类或一个方法可在不同类型的对象上进行操作。
  • 泛型所操作的数据类型被指定为一个参数,这个参数被称为类型参数(type parameters)。
  • 泛型类的定义是在类名后面加上,泛型接口的定义是在接口名后面加上,而泛型方法的定义是在方法的返回值前面加上,其头部定义分别如下:
泛型类的定义:[修饰符] class 类名<T>
泛型接口的定义:[public] interface 接口名<T>
泛型方法的定义:[public][static] <T> 返回值类型 方法名(T 参数)

a、类型参数名使用单个大写字母表示。
b、常用的类型参数名有:E(表示元素)、K(表示键)、N(表示数)、T(表示类型)、V(表示值)
c、在类和接口的声明中,可以有多个类型参数,但每个参数必须是唯一的

实战演练

例:泛型类Node

public class Node<T> {private T data;public Node() {}public Node(T data) {this.data = data;}public T getData() {return data;}public void setData(T data) {this.data = data;}public void showType() {System.out.println(" T的类型是:" +data.getClass().getName());}
}
  • 在使用泛型定义的类创建对象时,即在泛型类实例化时,也使用new运算符,但在类名后面需给出类型参数T的具体类型。
eg: Node<Integer> intNode = new Node<Integer>();Node<Integer> intNode = new Node<>();
  • 在泛型类实例化的过程中,实际类型必须是引用类型, 不能用int、double或char等这样的基本类型来替换类型参数T。

实战演练

public interface Entry<K,V> {public K getKey();public V getValue();
}
public class Pair<K,V> implements Entry<K,V>{private K key;private V value;public Pair(K key, V value) {this.key = key;this.value= value;}public void setKey(K key) {this.key = key;}public K getKey() {return key;}public void setValue(V vlaue) {this.value = value;}public V getValue() {return value;}public static void main(String[] args) {Pair<Integer,String> p1 = new Pair<>(20, "twenty");Pair<String,String> p2 = new Pair<>("China", "Beijing");System.out.println(p1.getValue());System.out.println(p2.getKey());}
}

在这里插入图片描述

泛型方法

  • 要定义泛型方法,只需将泛型的类型参数置于返回值前即可。
  • 在Java中,任何方法都可声明为泛型方法。
  • 只有声明了的方法才是泛型方法,泛型类中使用了泛型的成员方法并不是泛型方法。
  • 泛型方法除了定义不同,调用时与普通方法一样。
  • 推荐使用返回值类型和参数类型一致的泛型方法。

实战演练

例:Util.java

public class Util {public static <T> void swap(T[] array, int i, int j){T temp = array[i];array[i] = array[j];array[j] = temp;}public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {return p1.getKey().equals(p2.getKey()) &&p1.getValue().equals(p2.getValue());}public static void main(String[] args) {Integer[] numbers = {1, 3, 5, 7};Util.<Integer>swap(numbers, 0, 3);for(Integer n:numbers){System.out.println(n + “ ”);   // 输出7 3 5 1}Pair<Integer, String> p1 = new Pair<>(1, "apple");Pair<Integer, String> p2 = new Pair<>(1, "apple");boolean same = Util.<Integer,String>compare(p1, p2);System.out.println(same);     // 输出true}
}    

在这里插入图片描述

通配符(?)的使用

  • 泛型类型本身是一个Java类型,为泛型类型传递不同的类型参数会产生不同的类型。
ArrayList<Object> list1 = new ArrayList<Object>();
ArrayList<String> list2 = new ArrayList<String>();
  • 尽管String是Object的子类,但ArrayList并不是ArrayList的子类型。
  • 把ArrayList对象传递给一个需要ArrayList对象的方法,将会产生一个编译错误。
//打印传递列表的所有元素
public static void printList(List<Object> list){for(Object element: list){System.out.println(element);}
}

如何使上述方法可打印任意类型的列表?
       
     通配符(?)List<?> list

实战演练

例:WildCardDemo.java

import java.util.*;
public class WildCardDemo {public static void printList(List<?> list){for(Object element : list)System.out.print(element+" ");}public static void main(String[] args) {List<Integer> myList1 = new ArrayList<>();List<String> myList2 = new ArrayList<>();myList1.add(3);myList1.add(5);myList2.add("three");myList2.add("five");printList(myList1);System.out.println();printList(myList2);}
}

在这里插入图片描述

有界类型参数

  • 有时需要限制泛型类的类型参数,这就需要使用有界类型参数(bounded type parameter)。
  • 有界类型分为上界和下界:
  • 上界用extends指定:泛型类名<? extends T>
    含义:传递的类型参数是T类或是继承类T的子类或是实现接口T的类类型
  • 下界用super指定:泛型类名<? super T>
    含义:传递的类型参数是类T或类T的父类的某种类型

实战演练

例1:

Demo11_1<extends List> x = null;
x = new Demo11_1<LinkedList>( );  //正确
x = new Demo11_1<ArrayList>( );    //正确
x = new Demo11_1<HashMap>( );    //编译错误

java.util. LinkedList 和java.util. ArrayList类都实现了List接口
例2:BoundedTypeDemo.java

import java.util.*;
public class BoundedTypeDemo {public static double getAverage(List<? extends Number> numberList){double total = 0.0;for(Number number :numberList)total += number.doubleValue();return total/numberList.size();}public static void main(String[] args) {List<Integer> integerList = new ArrayList<Integer>();integerList.add(3);integerList.add(30);integerList.add(300);System.out.println(getAverage(integerList));  // 111.0    List<Double> doubleList = new ArrayList<>();doubleList.add(5.5);doubleList.add(55.5);System.out.println(getAverage(doubleList));  // 30.5}
}

在这里插入图片描述

继承泛型类与实现泛型接口

  • 被定义为泛型的类或接口可被继承与实现。
  • 泛型类的继承:
public class ExtendClass<T1>
{  }
class SubClass<T1,T2,T3> extends ExtendClass<T1>
{  }
  • 泛型接口的实现:
interface Face<T1>`package shujia_test1;public class Point<T extends Number> {// 成员变量private T x;private T y;// 构造方法public Point(T x, T y) {this.x = x;this.y = y;}// Getter 和 Setterpublic T getX() {return x;}public void setX(T x) {this.x = x;}public T getY() {return y;}public void setY(T y) {this.y = y;}// translate 方法,将点移动到新的坐标public void translate(T dx, T dy) {// 由于 T 是 Number 的子类,我们可以安全地调用 doubleValue()double dxDouble = dx.doubleValue();double dyDouble = dy.doubleValue();// 这里我们假设 x 和 y 也应该是可以转换为 double 的 Number 类型double xDouble = this.x.doubleValue();double yDouble = this.y.doubleValue();// 进行计算double newX = xDouble + dxDouble;double newY = yDouble + dyDouble;// 现在我们需要将结果转换回 T 类型。但是,由于类型擦除,我们不能直接这样做。// 一个简单的解决方案是抛出一个异常或要求调用者提供一个转换函数。// 但为了演示,我们假设 T 是 Double(这在实际应用中可能不是一个好主意)if (this.x instanceof Double && dx instanceof Double) {this.x = (T) Double.valueOf(newX); // 这里有一个不安全的类型转换,但在某些情况下是可行的this.y = (T) Double.valueOf(newY); // 同样,这里也有一个不安全的类型转换} else {// 处理其他情况,比如当 T 不是 Double 时throw new ClassCastException("Unsupported operation for non-Double types.");}// 或者,更好的方法是接受精度损失,并始终将 x 和 y 存储为 double(如果适用)}// 主方法,用于演示public static void main(String[] args) {// 创建Point<Integer>对象Point<Integer> pointInt = new Point<>(1, 2);System.out.println("Integer Point: (" + pointInt.getX() + ", " + pointInt.getY() + ")");pointInt.translate(3, 4);System.out.println("Translated Integer Point: (" + pointInt.getX() + ", " + pointInt.getY() + ")");// 创建Point<Double>对象Point<Double> pointDouble = new Point<>(1.5, 2.5);System.out.println("Double Point: (" + pointDouble.getX() + ", " + pointDouble.getY() + ")");pointDouble.translate(3.5, 4.5);System.out.println("Translated Double Point: (" + pointDouble.getX() + ", " + pointDouble.getY() + ")");}
}
`
{  }
class SubClass<T1,T2 > implements Face<T1>
{  }

🐱综合练习

定义一个泛型类Point,其中包含x和y两个类型为T的成员,定义带两个参数的构造方法,为x和y定义setter和getter,另外定义translate()方法将点移动到新的坐标。编写main()方法,创建Point对象和Point对象。

package shujia_test1;public class Point<T extends Number> {// 成员变量private T x;private T y;// 构造方法public Point(T x, T y) {this.x = x;this.y = y;}// Getter 和 Setterpublic T getX() {return x;}public void setX(T x) {this.x = x;}public T getY() {return y;}public void setY(T y) {this.y = y;}// translate 方法,将点移动到新的坐标public void translate(T dx, T dy) {// 由于 T 是 Number 的子类,我们可以安全地调用 doubleValue()double dxDouble = dx.doubleValue();double dyDouble = dy.doubleValue();// 这里我们假设 x 和 y 也应该是可以转换为 double 的 Number 类型double xDouble = this.x.doubleValue();double yDouble = this.y.doubleValue();// 进行计算double newX = xDouble + dxDouble;double newY = yDouble + dyDouble;// 现在我们需要将结果转换回 T 类型。但是,由于类型擦除,我们不能直接这样做。// 一个简单的解决方案是抛出一个异常或要求调用者提供一个转换函数。// 但为了演示,我们假设 T 是 Double(这在实际应用中可能不是一个好主意)if (this.x instanceof Double && dx instanceof Double) {this.x = (T) Double.valueOf(newX); // 这里有一个不安全的类型转换,但在某些情况下是可行的this.y = (T) Double.valueOf(newY); // 同样,这里也有一个不安全的类型转换} else {// 处理其他情况,比如当 T 不是 Double 时throw new ClassCastException("Unsupported operation for non-Double types.");}// 或者,更好的方法是接受精度损失,并始终将 x 和 y 存储为 double(如果适用)}// 主方法,用于演示public static void main(String[] args) {// 创建Point<Integer>对象Point<Integer> pointInt = new Point<>(1, 2);System.out.println("Integer Point: (" + pointInt.getX() + ", " + pointInt.getY() + ")");pointInt.translate(3, 4);System.out.println("Translated Integer Point: (" + pointInt.getX() + ", " + pointInt.getY() + ")");// 创建Point<Double>对象Point<Double> pointDouble = new Point<>(1.5, 2.5);System.out.println("Double Point: (" + pointDouble.getX() + ", " + pointDouble.getY() + ")");pointDouble.translate(3.5, 4.5);System.out.println("Translated Double Point: (" + pointDouble.getX() + ", " + pointDouble.getY() + ")");}
}

博主用心写,读者点关注,互动传真情,知识不迷路。

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

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

相关文章

Vue 的安装与配置

今天是八月一日&#xff0c;我也开启了Vue的学习&#xff0c;希望和大家一起学编程&#xff0c;相互督促&#xff0c;相互进步&#xff01; 安装vscode 安装Node.js 官网&#xff1a;https://nodejs.org/zh-cn 下载完正常安装就行 可以winr输入cmd&#xff0c;也可以vscod…

springboot智能健康管理平台-计算机毕业设计源码57256

摘要 在当今社会&#xff0c;人们越来越重视健康饮食和健康管理。借助SpringBoot框架和MySQL数据库的支持&#xff0c;开发智能健康管理平台成为可能。该平台结合了小程序技术的便利性和SpringBoot框架的快速开发能力&#xff0c;为用户提供了便捷的健康管理解决方案。 通过智能…

【多线程】单例模式

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1. 什么是单例模式1.1 理解单例模式1.2 单例模式的特点 2. 饿汉模式3. 懒汉模式3.1 单线程下的懒…

中国人民解放军建军97周年

缅怀先烈&#xff0c;砥砺前行 付吾辈之韶华&#xff0c;耀吾辈之中华! 万里河山&#xff0c;有您心安!

Django REST Framework(十五)路由Routes

如何在Django REST framework中利用SimpleRouter和DefaultRouter来高效生成视图集的路由信息,并详细解释如何使用action装饰器为视图集中的自定义方法生成路由 1.路由的定义规则 路由称为URL(Uniform Resource Locator,统一资源定位符),也可以称为URLconf,是对可以从互联…

【Java题解】杨辉三角—力扣

&#x1f389;欢迎大家收看&#xff0c;请多多支持&#x1f339; &#x1f970;关注小哇&#xff0c;和我一起成长&#x1f680;个人主页&#x1f680; ⭐目前主更 专栏Java ⭐数据结构 ⭐已更专栏有C语言、计算机网络⭐ 题目链接&#xff1a;杨辉三角 目录&#x1f451; ⭐题…

the request was rejected because no multipart boundary was found

文章目录 1. 需求描述2. 报错信息3. 探索过程1. 使用postman 排除后端错误2. 搜索网上的解决方法3. 解决方法 1. 需求描述 想要在前端上传一个PDF 发票&#xff0c;经过后端解析PDF之后&#xff0c;将想要的值自动回填到对应的输入框中 2. 报错信息 org.apache.tomcat.util.…

2024年有哪些开放式耳机值得入手?值得关注的开放式耳机评测大赏

如今&#xff0c;开放式耳机越来越受到人们的关注。2024 年更是涌现出了众多优秀的开放式耳机产品。但在众多选择面前&#xff0c;哪一款耳机的音质更出色&#xff1f;哪一款佩戴起来更舒适&#xff1f;又有哪一款在通话质量和连接性能上表现更优异呢&#xff1f;接下来我将详细…

【Devops】CertD 完全免费、自动申请、自动部署SSL证书一站式管理工具 | 自动化HTTPS | 3个月SSL自动轮换

CertD CertD 是一个免费全自动申请和自动部署更新SSL证书的工具。 后缀D取自linux守护进程的命名风格&#xff0c;意为证书守护进程。 关键字&#xff1a;证书自动申请、证书自动更新、证书自动续期、证书自动续签 一、特性 本项目不仅支持证书申请过程自动化&#xff0c;还…

SpringMVC源码解析(二):请求执行流程

SpringMVC源码系列文章 SpringMVC源码解析(一)&#xff1a;web容器启动流程 SpringMVC源码解析(二)&#xff1a;请求执行流程 目录 前言DispatcherServlet入口一、获取HandlerExcutionChain(包括Handler)1、获取Handler1.1、通过request获取查找路径1.2、通过查找路径获取Han…

找工作很迷茫?程序员的岗位宝典来了!

随着数字化转型进展深入&#xff0c;大量数字化、智能化的岗位相继涌现。 但即使这样&#xff0c;大家依然认为&#xff0c;找到一份合适的工作实在是太&#xff01;难&#xff01;了&#xff01; 调查显示&#xff0c;技术创新和商业模式正在成为助推企业发展的两大动力。同时…

【iOS】——锁

五类锁 锁作为一种非强制的机制&#xff0c;被用来保证线程安全。每一个线程在访问数据或者资源前&#xff0c;要先获取&#xff08;Acquire&#xff09;锁&#xff0c;并在访问结束之后释放&#xff08;Release&#xff09;锁。如果锁已经被占用&#xff0c;其它试图获取锁的…

计算机网络必会面经

1.键入网址到网页显示&#xff0c;期间发生了什么 2.在TCP/IP网络模型中。TCP将数据进行分段后&#xff0c;为什么还需要IP层继续分片 3.详细说明tcp三次握手&#xff0c;为什么是三次&#xff0c;若每次握手丢了&#xff0c;解决办法是什么 4.详细说明tcp四次挥手&#xff…

【Python】python基础

本篇文章将讲解以下知识点&#xff1a; &#xff08;1&#xff09;循环语句 &#xff08;2&#xff09;字符串格式化 &#xff08;3&#xff09;运算符 一&#xff1a;循环语句 循环语句有两种&#xff1a;while for 本篇文章只讲解while循环 格式&#xff1a; whil…

Unity材质球自动遍历所需贴图

Unity材质球自动遍历所需贴图 文章目录 Unity材质球自动遍历所需贴图一、原理二、用法1.代码&#xff1a;2.使用方法 一、原理 例如一个材质球名为&#xff1a;Decal_Text_Cranes_01_Mat &#xff0c; 然后从全局遍历出&#xff1a;Decal_Text_Cranes_01_Albedo赋值给材质球的…

【网络基础】初识网络 {计算机网络背景;网络协议初识;网络传输基本流程;网络中的地址管理;网络设备简单介绍}

一、计算机网络背景 1.1 网络发展 计算机网络的发展可以追溯到20世纪60年代&#xff0c;那时候最初的计算机网络只是为了让科学家们能够共享计算机资源和数据。但是在20世纪80年代&#xff0c;互联网的出现彻底改变了计算机网络的面貌&#xff0c;使得人们可以随时随地通过互…

AI剪辑短视频以及账号管理矩阵工具系统搭建开发

目录 前言 一、系统有哪些功能&#xff1f; 二、怎么开发 前言 通过AI剪辑短视频以及生成短视频&#xff0c;以及对自媒体账号的管理功能的功能进行开发。这款系统能够批量混合剪辑视频然后一键发布到绑定好的自媒体账号里面。 一、系统有哪些功能&#xff1f; 1.AI智能文…

【深度学习实战(49)】目标检测损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU原理及Pytorch实现

前言 损失函数是用来评价模型的预测值和真实值一致程度&#xff0c;损失函数越小&#xff0c;通常模型的性能越好。不同的模型用的损失函数一般也不一样。损失函数主要是用在模型的训练阶段&#xff0c;如果我们想让预测值无限接近于真实值&#xff0c;就需要将损失值降到最低…

深入探讨RCE漏洞及其防御策略

1. RCE漏洞 1.1. 漏洞原理 远程代码执行&#xff08;RCE&#xff09;漏洞允许攻击者远程注入并执行操作系统命令或代码&#xff0c;从而控制后台系统。 1.2. 漏洞产生条件 调用第三方组件存在代码执行漏洞。用户输入内容作为系统命令参数拼接到命令中。对用户输入的过滤不严…

汽车雷达系统集成

汽车雷达系统集成是实现高级驾驶辅助系统&#xff08;ADAS&#xff09;和自动驾驶功能的重要环节&#xff0c;它涉及多种硬件和软件的协同工作。以下将详细讲解汽车雷达系统集成的各个方面&#xff1a; 雷达传感器选择 毫米波雷达&#xff1a;毫米波雷达主要使用24GHz和77GHz频…