当前位置: 首页 > news >正文

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集合框架是处理一组对象的标准方法。常见的集合包括ListSetMap。结合泛型使用集合,可以提高类型安全性和代码的可读性。

使用泛型集合
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类型的元素。

通配符

通配符用于在泛型中表示未知类型,有三种主要形式:

  1. 无界通配符<?>,表示任何类型。
  2. 有界通配符(上界)<? extends T>,表示类型T及其子类型。
  3. 有界通配符(下界)<? 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}
}

总结

通过以上更详细的解释和示例,我们可以更深入地理解泛型和集合的使用:

  1. 泛型类:定义包含类型参数的类,使用时指定具体类型。
  2. 泛型方法:定义包含类型参数的方法,使用时指定具体类型。
  3. 集合和泛型:使用泛型集合可以保证类型安全。
  4. 通配符:表示未知类型,提供更灵活的类型控制。
  5. 泛型和继承:使用通配符实现泛型的多态性。

相关文章:

Java 泛型与集合的深入解析:原理、应用与实践

泛型的基本原理 为什么需要泛型 在Java 5之前&#xff0c;Java的集合类只能存储Object类型的对象。这意味着&#xff0c;存储在集合中的对象在取出时需要进行类型转换&#xff0c;这不仅繁琐&#xff0c;而且容易出错。泛型通过在编译时进行类型检查&#xff0c;确保类型安全…...

Oracle 数据库的自动化工具:AWR 和 ASM

Oracle 数据库提供了一系列工具和技术&#xff0c;以提高数据库管理的效率和性能。其中&#xff0c;AWR和 ASM是两个关键组件。本文将详细介绍 AWR 和 ASM 的功能及其在数据库管理中的重要性。 AWR AWR 是 Oracle 数据库的一个核心部分&#xff0c;用于收集、处理和维护数据库…...

java技术专家面试指南50问【java学习+面试宝典】(五)

Dubbo需要 Web 容器吗&#xff1f; 不需要&#xff0c;如果硬要用 Web 容器&#xff0c;只会增加复杂性&#xff0c;也浪费资源。 一个字符串类型的值能存储最大容量是多少&#xff1f; 512M 什么是Kubectl&#xff1f; Kubectl是一个平台&#xff0c;您可以使用该平台将命…...

Elasticsearch之深入聚合查询

1、正排索引 1.1 正排索引&#xff08;doc values &#xff09;和倒排索引 概念&#xff1a;从广义来说&#xff0c;doc values 本质上是一个序列化的 列式存储 。列式存储 适用于聚合、排序、脚本等操作&#xff0c;所有的数字、地理坐标、日期、IP 和不分词&#xff08; no…...

大模型:分本分割模型

目录 一、文本分割 二、BERT文本分割模型 三、部署模型 3.1 下载模型 3.2 安装依赖 3.3 部署模型 3.4 运行服务 四、测试模型 一、文本分割 文本分割是自然语言处理中的一项基础任务&#xff0c;目标是将连续的文本切分成有意义的片段&#xff0c;这些片段可以是句子、…...

数据预处理 #数据挖掘 #python

数据分析中的预处理步骤是数据分析流程中的重要环节&#xff0c;它的目的是清洗、转换和整理原始数据&#xff0c;以便后续的分析能够准确、有效。预处理通常包括以下几个关键步骤&#xff1a; 数据收集&#xff1a;确定数据来源&#xff0c;可能是数据库、文件、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 二、配置数据库&#xff08;数据库文件名和路径&#xff09; 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里面 步骤如下&#xff1a; 1、首先打开project2 2、如图选择导出Fragment 3、选中自己想导出的模块&#xff08;可以不止一个&#xff09; 4、将其保存在桌面 5、打开project1 6、选择导入 7、选中刚刚…...

设计模式——外观模式

外观模式(Facade) 为系统中的一组接口提供一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。 #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对接企业微信审批接口的问题与解决办法(二)

在现代企业中&#xff0c;审批流程是非常重要的一环&#xff0c;它涉及到企业内部各种业务流程的规范和高效运转。而随着企业微信的流行&#xff0c;许多企业希望将审批流程整合到企业微信中&#xff0c;以实现更便捷的审批操作。本文将介绍如何使用PHP对接企业微信审批接口&am…...

RK3288 android7.1 实现ota升级时清除用户数据

一&#xff0c;OTA简介(整包&#xff0c;差分包) OTA全称为Over-The-Air technology(空中下载技术)&#xff0c;通过移动通信的接口实现对软件进行远程管理。 1. 用途&#xff1a; OTA两种类型最大的区别莫过于他们的”出发点“&#xff08;我们对两种不同升级包的创建&…...

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

在线工具站 推荐一个程序员在线工具站&#xff1a;程序员常用工具&#xff08;http://cxytools.com&#xff09;&#xff0c;有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具&#xff0c;效率加倍嘎嘎好用。 程序员资料站 推荐一个程序员编程资料站&#xff1a;…...

Java 异常处理 -- Java 语言的异常、异常链与断言

大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 009 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自…...

Spring Cloud Nacos 详解:服务注册与发现及配置管理平台

Spring Cloud Nacos 详解&#xff1a;服务注册与发现及配置管理平台 Spring Cloud Nacos 是 Spring Cloud 生态系统中的一个子项目&#xff0c;提供了服务注册与发现、配置管理等功能&#xff0c;基于 Alibaba 开源的 Nacos 项目。Nacos 是一个易于使用的动态服务发现、配置管…...

java多线程临界区介绍

在Java多线程编程中&#xff0c;"临界区"是指一段必须互斥执行的代码区域。当多个线程访问共享资源时&#xff0c;为了防止数据不一致或逻辑错误&#xff0c;需要确保同一时刻只有一个线程可以进入临界区。Java提供了多种机制来实现这一点&#xff0c;例如synchroniz…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...