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

news2024/11/14 21:22:48

在这里插入图片描述

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

  • 欢迎大家:这里是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 和 Setter
	public 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 和 Setter
	public 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.coloradmin.cn/o/1966265.html

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

相关文章

【数据结构-前缀哈希同余运算】力扣974. 和可被 K 整除的子数组

给定一个整数数组 nums 和一个整数 k &#xff0c;返回其中元素之和可被 k 整除的非空 子数组 的数目。 子数组 是数组中 连续 的部分。 示例 1&#xff1a; 输入&#xff1a;nums [4,5,0,-2,-3,1], k 5 输出&#xff1a;7 解释&#xff1a; 有 7 个子数组满足其元素之和可…

仿真入门!Hypermesh焊接处理方法

某抗硫球阀为对焊端结构&#xff0c;需要焊接袖管。焊接过程产生的高温会造成热影响区域&#xff0c;尤其接头区域产生变形及残余应力&#xff0c;同时O型密封圈处的温度也是焊接生产比较关心的问题。因此&#xff0c;为弄清袖管焊接过程中温度场规律&#xff0c;给实际焊接生产…

RAID 级别:0、1、5、6、10 和 50 傻傻分不清?那是你没看过这篇

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 早上好&#xff0c;我的网工朋友。 大家都知道&#xff0c;无论是企业级服务器还是个人计算机&#xff0c;数据的安全性和可用性都是至关重要的。…

通配符HTTPS证书快速申请流程

通配符HTTPS证书是一种特别类型的HTTPS证书&#xff0c;它可以为一个主域名及其下级所有子域名提供安全加密。这对于拥有多个子域名的企业来说非常有用&#xff0c;因为它简化了管理流程&#xff0c;并降低了成本。具体申请流程&#xff1a; 注册账号填写230919注册码即可获得…

【C++】实验十四

题目&#xff1a; 1、编写程序&#xff0c;输入a&#xff0c;b&#xff0c;c&#xff0c;检查a&#xff0c;b&#xff0c;c是否满足以下条件&#xff0c;如不满足&#xff0c;由cerr输出有关错误信息。 2、从键盘输入一批数值。要求保留3位小数&#xff0c;在输出时上下行小数…

成都夏光汝网络科技有限公司抖音小店品质与创新的完美结合

在数字经济蓬勃发展的今天&#xff0c;电商行业以其独特的魅力和无限的可能性&#xff0c;正深刻改变着我们的消费习惯与生活方式。其中&#xff0c;抖音小店作为短视频与电商结合的典范&#xff0c;更是以其独特的优势迅速崛起&#xff0c;成为广大消费者喜爱的购物渠道。成都…

企业版邮箱如何确保全球畅邮

企业版邮箱如何确保全球畅邮呢&#xff1f;一邮箱通过多项国际隐私认证&#xff0c;加密技术保障数据安全。二是全球网络部署确保邮件畅通。三提供灵活价格方案&#xff0c;支持用户定制化和跨平台。四是第三方工具集成&#xff0c;提升效率。 一、Zoho邮箱的安全保障 1.1 高…

【Stable Diffusion】影楼再也赚不到你的钱,让SD帮你“拍摄”艺术写真

前言 点击上方「蓝字」关注我们 你能看出下图是一张经过AI技术处理过的写真吗&#xff1f; 通过原图AI合成&#xff0c;简单几步操作&#xff0c;一个无需摄影无需后期的0成本摄影工作室就诞生了。 今天就来教大家怎么用Stable Diffusion做出这样的写真效果。 操作过程 第一…

IDEA使用Docker打包镜像

IDEA使用Docker打包镜像 Docker服务器 想要使用idea直接打包docker镜像&#xff0c;需要一个docker服务&#xff0c;你可以安装windows版本的docker&#xff0c;或者安装Linux版本的docker到虚拟机中&#xff0c;这个根据个人想法即可。本篇文章使用的是Linux&#xff01; W…

一图搞懂,全流程项目管理实践地图,驱动:市场-研发-售后

如何共同协作驱动 市场研发售后&#xff1f; 软件项目交付需要一段时间和长周期&#xff0c;而由于产品研发团队前与市场部门脱节、后又与售后支撑服务团队脱节的话&#xff0c;整体上会加剧项目管理的成本和内部跨部门协作的难度。 如何高效共同协作驱动 市场运营产品研发售…

C# Solidworks二次开发------设置按键打开模型查询

一、代码 public void Open_File(string FileNmae) {Process.Start("explorer.exe", FileNmae); }Open_File("路径"); 二、内容 这个代码很简单&#xff0c;我使用其主要的作用是设置一个按键&#xff0c;可以快速的查看我们已生成的三维模型&#xff0…

2000-2023年上市公司融资约束指数-KZ指数(含原始数据+计算结果)

2000-2023年上市公司融资约束指数-KZ指数&#xff08;含原始数据计算结果&#xff09; 1、时间&#xff1a;2000-2023年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;证券代码、证券简称、统计截止日期、是否剔除ST或*ST或PT股、是否剔除上市不满一年、已经退市或被…

js数据类型基础

最近投了几家公司面试&#xff0c;其中有一家公司面试官面试我非常感谢他&#xff0c;感觉他像一位老师的角色对于我回答不上来的问题以及回答错误的问题耐心指导。js基础真的很重要&#xff01;&#xff01;面完之后我觉平常我只是看到了问题的表面&#xff0c;并没有深度的了…

基于SpringBoot的电商购物平台设计与实现-计算机毕设 附源码 06411

基于SpringBoot的电商购物平台设计与实现 摘 要 该电商购物平台基于SpringBoot开发&#xff0c;旨在为用户提供便捷的购物体验。注册功能允许用户通过提供账号、密码、昵称、邮箱等信息注册账户&#xff0c;而已注册用户可以使用用户名和密码登录系统。普通用户可以在首页查看…

钉钉机器人调度

钉钉机器人调度 流程操作钉钉开发者后台配置01 添加机器人获取APPKEY和APPSECRET获取权限开启消息推送 02 接收“问题”搭建接口 03 转发到服务器服务器的管理界面机器人配置界面将代码上传到服务器 04 API调度影刀提取数据配置信息--合法性 05 生成答案06 回传到服务器 流程 操…

WPF中添加布局拖拽功能 (添加GridSplitter)

1. 思想&#xff1a; 使用GridSplitter加到布局中&#xff0c;作为控件。 2. Xaml代码&#xff1a; <Windowx:Class"TestWPF_Func1207.TestRichTextBox"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schema…

牛客JS题(十五)参数解析器

注释很详细&#xff0c;直接上代码 涉及知识点&#xff1a; decodeURIComponent(URL解码函数)new URL正则exec 题干&#xff1a; 我的答案 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /></head><body&…

光流传感器 - 从零开始认识各种传感器【第二十二期】

光流传感器|从零开始认识各种传感器 1、什么是光流传感器 光流传感器是一种用于测量物体相对于周围环境的运动的设备。它通过检测周围光线的变化来计算出物体的运动方向和速度&#xff0c;广泛应用于机器人导航、无人机飞行控制、虚拟现实等领域。 2、光流传感器是如何工作的…

java8通用启动参数

由于默认的jvm参数不够合理&#xff0c;一般使用前都建议按需调整&#xff0c;这里尝试抛砖引玉&#xff0c;给出我个人工作中总结的经验&#xff0c;欢迎大家一起讨论 服务类型 http应用dubbo应用 java版本 使用java8支持容器化的版本&#xff1a;Java 8 Update 261 (8u26…

【吊打面试官系列-Dubbo面试题】Dubbo 如何优雅停机?

大家好&#xff0c;我是锋哥。今天分享关于 【Dubbo 如何优雅停机&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Dubbo 如何优雅停机&#xff1f; Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的&#xff0c;所以如果使用 kill -9 PID 等强制关闭指令&am…