Java 泛型与集合的深入解析:原理、应用与实践
泛型的基本原理
为什么需要泛型
在Java 5之前,Java的集合类只能存储Object
类型的对象。这意味着,存储在集合中的对象在取出时需要进行类型转换,这不仅繁琐,而且容易出错。泛型通过在编译时进行类型检查,确保类型安全,减少了运行时错误。
泛型的定义
泛型通过类型参数来实现,这些类型参数在使用时被具体的类型替换。常见的类型参数命名如下:
T
:Type(类型)E
:Element(元素)K
:Key(键)V
:Value(值)
泛型类
泛型类是在类定义中使用类型参数。例如:
class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
}
在使用泛型类时,需要指定具体的类型:
public class GenericClassExample {public static void main(String[] args) {Box<String> stringBox = new Box<>();stringBox.setContent("Hello, World!");System.out.println(stringBox.getContent()); // 输出: Hello, World!Box<Integer> integerBox = new Box<>();integerBox.setContent(123);System.out.println(integerBox.getContent()); // 输出: 123}
}
泛型方法
泛型方法是在方法定义中使用类型参数。类型参数在方法名之前用尖括号<>
指定。例如:
public class GenericMethodExample {public static <T> void printArray(T[] array) {for (T element : array) {System.out.print(element + " ");}System.out.println();}public static void main(String[] args) {Integer[] intArray = {1, 2, 3, 4, 5};String[] stringArray = {"A", "B", "C", "D", "E"};printArray(intArray); // 输出: 1 2 3 4 5 printArray(stringArray); // 输出: A B C D E }
}
泛型和集合
Java集合框架是处理一组对象的标准方法。常见的集合包括List
、Set
和Map
。结合泛型使用集合,可以提高类型安全性和代码的可读性。
使用泛型集合
import java.util.ArrayList;
import java.util.List;public class GenericCollectionExample {public static void main(String[] args) {// 创建一个用于存储字符串的泛型列表List<String> stringList = new ArrayList<>();// 向列表中添加字符串stringList.add("Hello");stringList.add("World");// 使用增强型 for 循环遍历并打印列表中的每个字符串for (String str : stringList) {System.out.println(str);}}
}
//程序运行后,输出结果为:
//Hello
//World
在这个例子中,List<String>
确保了stringList
只能包含String
类型的元素。
通配符
通配符用于在泛型中表示未知类型,有三种主要形式:
- 无界通配符:
<?>
,表示任何类型。 - 有界通配符(上界):
<? extends T>
,表示类型T及其子类型。 - 有界通配符(下界):
<? super T>
,表示类型T及其父类型。
无界通配符
无界通配符<?>
表示任何类型。例如:
import java.util.ArrayList;
import java.util.List;public class WildcardExample {public static void printList(List<?> list) {for (Object elem : list) {System.out.print(elem + " ");}System.out.println();}public static void main(String[] args) {List<Integer> intList = new ArrayList<>();intList.add(1);intList.add(2);intList.add(3);List<String> stringList = new ArrayList<>();stringList.add("A");stringList.add("B");stringList.add("C");printList(intList); // 输出: 1 2 3 printList(stringList); // 输出: A B C }
}
有界通配符(上界)
有界通配符<? extends T>
表示类型T及其子类型。例如:
import java.util.ArrayList;
import java.util.List;public class BoundedWildcardExample {public static double sumOfList(List<? extends Number> list) {double sum = 0.0;for (Number number : list) {sum += number.doubleValue();}return sum;}public static void main(String[] args) {List<Integer> intList = new ArrayList<>();intList.add(1);intList.add(2);intList.add(3);List<Double> doubleList = new ArrayList<>();doubleList.add(1.1);doubleList.add(2.2);doubleList.add(3.3);System.out.println("Sum of intList: " + sumOfList(intList)); // 输出: Sum of intList: 6.0System.out.println("Sum of doubleList: " + sumOfList(doubleList)); // 输出: Sum of doubleList: 6.6}
}
有界通配符(下界)
有界通配符<? super T>
表示类型T及其父类型。例如:
import java.util.ArrayList;
import java.util.List;public class LowerBoundedWildcardExample {public static void addNumbers(List<? super Integer> list) {list.add(1);list.add(2);list.add(3);}public static void main(String[] args) {List<Number> numberList = new ArrayList<>();addNumbers(numberList);for (Number number : numberList) {System.out.println(number);}}
}
泛型和继承
泛型不支持多态,例如,List<Number>
不能被赋值为List<Integer>
。但是可以通过使用通配符来实现类似的效果。
示例:泛型和继承
import java.util.ArrayList;
import java.util.List;class Person {private String name;public Person(String name) {this.name = name;}public String getName() {return name;}
}class Employee extends Person {public Employee(String name) {super(name);}
}public class GenericInheritanceExample {public static void printNames(List<? extends Person> people) {for (Person person : people) {System.out.println(person.getName());}}public static void main(String[] args) {List<Employee> employees = new ArrayList<>();employees.add(new Employee("Alice"));employees.add(new Employee("Bob"));printNames(employees); // 输出: Alice Bob}
}
总结
通过以上更详细的解释和示例,我们可以更深入地理解泛型和集合的使用:
- 泛型类:定义包含类型参数的类,使用时指定具体类型。
- 泛型方法:定义包含类型参数的方法,使用时指定具体类型。
- 集合和泛型:使用泛型集合可以保证类型安全。
- 通配符:表示未知类型,提供更灵活的类型控制。
- 泛型和继承:使用通配符实现泛型的多态性。
相关文章:
Java 泛型与集合的深入解析:原理、应用与实践
泛型的基本原理 为什么需要泛型 在Java 5之前,Java的集合类只能存储Object类型的对象。这意味着,存储在集合中的对象在取出时需要进行类型转换,这不仅繁琐,而且容易出错。泛型通过在编译时进行类型检查,确保类型安全…...
Oracle 数据库的自动化工具:AWR 和 ASM
Oracle 数据库提供了一系列工具和技术,以提高数据库管理的效率和性能。其中,AWR和 ASM是两个关键组件。本文将详细介绍 AWR 和 ASM 的功能及其在数据库管理中的重要性。 AWR AWR 是 Oracle 数据库的一个核心部分,用于收集、处理和维护数据库…...
java技术专家面试指南50问【java学习+面试宝典】(五)
Dubbo需要 Web 容器吗? 不需要,如果硬要用 Web 容器,只会增加复杂性,也浪费资源。 一个字符串类型的值能存储最大容量是多少? 512M 什么是Kubectl? Kubectl是一个平台,您可以使用该平台将命…...
Elasticsearch之深入聚合查询
1、正排索引 1.1 正排索引(doc values )和倒排索引 概念:从广义来说,doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作,所有的数字、地理坐标、日期、IP 和不分词( no…...
大模型:分本分割模型
目录 一、文本分割 二、BERT文本分割模型 三、部署模型 3.1 下载模型 3.2 安装依赖 3.3 部署模型 3.4 运行服务 四、测试模型 一、文本分割 文本分割是自然语言处理中的一项基础任务,目标是将连续的文本切分成有意义的片段,这些片段可以是句子、…...
数据预处理 #数据挖掘 #python
数据分析中的预处理步骤是数据分析流程中的重要环节,它的目的是清洗、转换和整理原始数据,以便后续的分析能够准确、有效。预处理通常包括以下几个关键步骤: 数据收集:确定数据来源,可能是数据库、文件、API或网络抓取…...
VS2022 使用C++访问 mariadb 数据库
首先,下载 MariaDB Connector/C++ 库 MariaDB Products & Tools Downloads | MariaDB 第二步,安装后 第三步,写代码 #include <iostream> #include <cstring> #include <memory> #include <windows.h>#include <mariadb/conncpp.hpp>…...
kotlin 语法糖
Use of “when” Expression Instead of “switch” fun getDayOfWeek(day: Int): String {return when (day) {1 -> "Monday"2 -> "Tuesday"3 -> "Wednesday"4 -> "Thursday"5 -> "Friday"6 -> "Sa…...
.NET MAUI Sqlite数据库操作(一)
一、安装 NuGet 包 安装 sqlite-net-pcl 安装 SQLitePCLRawEx.bundle_green 二、配置数据库(数据库文件名和路径) namespace TodoSQLite; public static class Constants {public const string DatabaseFilename "TodoSQLite.db3";//数据库…...
SQL 窗口函数
1.窗口函数之排序函数 RANK, DENSE_RANK, ROW_NUMBER RANK函数 计算排序时,如果存在相同位次的记录,则会跳过之后的位次 有 3 条记录排在第 1 位时: 1 位、1 位、1 位、4 位…DENSE_RANK函数 同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次 有 3 条记录排在…...
staruml怎么合并多个Project工程文件
如图现在有两个staruml文件 现在我想要把project2合并到project1里面 步骤如下: 1、首先打开project2 2、如图选择导出Fragment 3、选中自己想导出的模块(可以不止一个) 4、将其保存在桌面 5、打开project1 6、选择导入 7、选中刚刚…...
设计模式——外观模式
外观模式(Facade) 为系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 #include <iostream>using namespace std;// 四个系统子类 class SubSystemOne { public:void MethodOne(){cout <&l…...
开源-Docker部署Cook菜谱工具
开源-Docker部署Cook菜谱工具 文章目录 开源-Docker部署Cook菜谱工具介绍资源列表基础环境一、安装Docker二、配置加速器三、查看Docker版本四、拉取cook镜像五、部署cook菜谱工具5.1、创建cook容器5.2、查看容器运行状态5.3、查看cook容器日志 六、访问cook菜谱服务6.1、访问c…...
使用PHP对接企业微信审批接口的问题与解决办法(二)
在现代企业中,审批流程是非常重要的一环,它涉及到企业内部各种业务流程的规范和高效运转。而随着企业微信的流行,许多企业希望将审批流程整合到企业微信中,以实现更便捷的审批操作。本文将介绍如何使用PHP对接企业微信审批接口&am…...
RK3288 android7.1 实现ota升级时清除用户数据
一,OTA简介(整包,差分包) OTA全称为Over-The-Air technology(空中下载技术),通过移动通信的接口实现对软件进行远程管理。 1. 用途: OTA两种类型最大的区别莫过于他们的”出发点“(我们对两种不同升级包的创建&…...
okHttp的https请求忽略ssl证书认证
使用okhttp请求第三方https接口返回异常 sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target意思就是非安全的调用&#…...
在Java中使用Spring Boot设置全局的BusinessException
在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。 程序员资料站 推荐一个程序员编程资料站:…...
Java 异常处理 -- Java 语言的异常、异常链与断言
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 009 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自…...
Spring Cloud Nacos 详解:服务注册与发现及配置管理平台
Spring Cloud Nacos 详解:服务注册与发现及配置管理平台 Spring Cloud Nacos 是 Spring Cloud 生态系统中的一个子项目,提供了服务注册与发现、配置管理等功能,基于 Alibaba 开源的 Nacos 项目。Nacos 是一个易于使用的动态服务发现、配置管…...
java多线程临界区介绍
在Java多线程编程中,"临界区"是指一段必须互斥执行的代码区域。当多个线程访问共享资源时,为了防止数据不一致或逻辑错误,需要确保同一时刻只有一个线程可以进入临界区。Java提供了多种机制来实现这一点,例如synchroniz…...
基于JSP的超市管理系统
你好呀,我是计算机学长猫哥!如果有相关需求,文末可以找到我的联系方式。 开发语言:Java 数据库:MySQL 技术:JSP MyBatis 工具:IDEA/Eclipse、Navicat、Maven 系统展示 员工管理界面图 管…...
一文讲清:生产报工系统的功能、报价以及如何选择
最近这几年,企业越来越注重生产的速度和成本,尤其是“性价比”,生产报工系统已经变成了制造业里不可或缺的一部分。不过,市场上生产报工系统的选择太多,价格也都不一样,这就给很多企业出了个难题࿱…...
blender bpy将顶点颜色转换为UV纹理vertex color to texture
一、关于环境 安装blender的bpy,不需要额外再安装blender软件。在python控制台中直接输入pip install bpy即可。 二、关于代码 本文所给出代码仅为参考,禁止转载和引用,仅供个人学习。 本文所给出的例子是https://download.csdn.net/downl…...
Flink Sql:四种Join方式详解(基于flink1.15官方文档)
JOINs flink sql主要有四种连接方式,分别是Regular Joins、Interval Joins、Temporal Joins、lookup join 1、Regular Joins(常规连接 ) 这种连接方式和hive sql中的join是一样的,包括inner join,left joinÿ…...
(delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第3节(泛型约束)
14.3 泛型约束 正如我们所看到的,您在泛型类的方法中可以做的事情非常少。您可以传递它(即分配它)并执行上面我介绍的泛型类型函数允许的有限操作。 为了能够执行泛型类的实际操作,通常需要对其进行约束。例如,…...
C语言详解(预编译)
Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…...
解决el-table表格拖拽后,只改变了数据,表头没变的问题
先看看是不是你想要解决的问题 拖拽后表头不变的bug修复 这个问题一般是使用v-for对column的数据进行循环的时候,key值绑定的是个index导致的,请看我上篇文章:eleplus对el-table表格进行拖拽(使用sortablejs进行列拖拽和行拖拽):-…...
简单塔防小游戏
学习目标:熟悉塔防游戏核心战斗 游戏画面 项目结构目录 核心代码: if ( Input.GetMouseButtonDown(0)){if (EventSystem.current.IsPointerOverGameObject()false){//开发炮台的建造Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);Rayca…...
高考之后第一张大流量卡应该怎么选?
高考之后第一张大流量卡应该怎么选? 高考结束后,选择一张合适的大流量卡对于准大学生来说非常重要,因为假期期间流量的使用可能会暴增。需要综合考虑多个因素,以确保选到最适合自己需求、性价比较高且稳定的套餐。以下是一些建议…...
如何从微软官方下载Edge浏览器的完整离线安装包
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 正文内容 📒🚀 官方直链下载🚬 手动选择下载🎈 获取方式 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 在网上搜索Microsoft Edge浏览器的离线安装包时,很多用户都会发现大部分都是在线安装包,无法满足他们在无网络环境下进…...
网站屏蔽右键破解/免费的外链网站
错误 无法为源卷创建 VSS 快照。错误代码: 2147549183 (0x8000FFFF)。 环境 使用vmware converter 对 windows 物理机迁移到 esxi 虚拟机中,在任务栏91%处出现如上错误 解决方法 检查 是否有 Volume Shadow Copy (vss) 服务 ,或者 Volume Shadow Copy 是否开启…...
域名申请到网站建设教程/软件商店安装
更多内容 请关注【广通信达】 做网络维护管理的人都知道,网络分为内网和外网。内网安全强调的是数据安全、运行安全和管理安全,而其核心是数据安全和管理安全,同时内网安全之技术涉及隐私的考虑。1、内网安全的本质最近一两年信息泄露的案例屡…...
销售网站建设常遇到的问题/网络营销网站建设
信息时代下,企业对于管理软件的需求日益增加,对于开发的效率要求也不断提高。低代码和无代码平台的出现,打破了企业传统的软件开发模式。但是二者名称上的一字之差,让大家产生了疑惑:低代码和代码一样吗?无…...
博客系统做网站/宁波网站推广优化哪家正规
CentOS7 Linux yum 安装 Redis1. 安装redis下载fedora的epel仓库yum install epel-release安装redis数据库yum install redis安装完毕后,使用下面的命令启动redis服务# 启动redisservice redis start# 停止redisservice redis stop# 查看redis运行状态service redis…...
做网站好还是做安卓app好/seo站长博客
MySQL 为日期增加一个时间间隔:date_add() now() //now函数为获取当前时间 select date_add(now(), interval 1 day); - 加1天 select date_add(now(), interval 1 hour); -加1小时 select date_add(now(), interval 1 minute); - 加1分钟 select date_add(no…...
网上接手袋做是哪一个网站/跨境电商怎么做
用dockerfile构建一个Java的web环境,主要分为2步,第一步是在镜像中安装jdk并配置环境变量,第二步是安装tomcat。先贴一下完整的dockerfileFROM ubuntu:14.04MAINTAINER *** "*********.com"RUN apt-get updateADD jdk-8u77-linux-x…...