Java 核心--泛型枚举

作者:IvanCodes

发布时间:2025年4月30日🤓

专栏:Java教程


各位 CSDN伙伴们,大家好!👋 写了那么多代码,有没有遇到过这样的“惊喜”:满心欢喜地从 ArrayList 里取出数据,想当然地以为它是个 String,结果一运行,“啪”!一个 ClassCastException 甩在脸上?😵‍💫 或者,为了表示几个固定的状态(比如订单处理中、已发货),用了 1, 2, 3 这样的“魔法数字”🧙‍♂️,过段时间自己都忘了哪个数字对应哪个状态?🤦‍♀️

别担心,这些都是新手(甚至老手!)路上常见的“坑”。好在 Java 提供了两大利器来帮我们填坑:泛型 (Generics) 和 枚举 (Enums)!它们就像给我们的代码上了双重保险,让代码更安全、更易懂。今天,我们就来把这两个“保险”搞明白!🛠️✨

一、 泛型 (<T>):类型的“占位符”,安全的“万能容器

还记得那个什么都能装Object 类型的 ArrayList 吗?它就像一个不透明大麻袋 🛍️,苹果 🍎、书 📚、玩具 🧸 都能往里扔。方便是方便,可往外取的时候就麻烦了——你得里面是啥,然后强制转换类型。万一猜错了… 运行时就了!💥

泛型 就是来解决这个问题的救星!它的核心思想,说白了就是:把类型检查这活儿,从不靠谱的运行时,提前到靠谱的编译时搞定! 并且顺便让代码更好看、更好用。

它是怎么做到的呢?通过引入 类型参数 (Type Parameters)——你可以把它想象成一个类型的“占位符” (常写成 <T>, <E> 这类大写字母)。在定义类、接口或方法的时候,先用这个占位符代表“未来的某种类型”。等到实际使用的时候,再明确告诉编译器:“嘿,这次这个 <T> 代表的是 String!”或者“这次 <E> 代表 Integer!”

1.1 泛型带来的实实在在的好处

  • 类型安全 <✅>:编译器成了你的“类型警察”👮‍♀️。你往 ArrayList<String> 里塞个 Integer编译时就给你拦下来!再也不会有运行时的 ClassCastException 意外了。
  • 告别强制类型转换 <✨>:既然编译器已经帮你把好关了,从 ArrayList<String> 里取出来的元素,它百分百就是 String!再也不用写 (String) 这种难看又可能出错的代码了。代码瞬间清爽不少!
  • 代码更通用、复用性更高 <🔄>:想想 ArrayList<T>,一份代码就能搞定 ArrayList<String>, ArrayList<Integer>, ArrayList<YourCustomClass>… 这就是泛型带来的代码复用魔力。

1.2 怎么玩转泛型

1.2.1 泛型类 <📦>

最常见的用法,定义一个可以持有特定类型对象的类。

// 一个“类型安全”的盒子
public class Box<T> { // <T> 是类型占位符private T item; // 里面的东西是 T 类型public void setItem(T item) {this.item = item;}public T getItem() {return item;}public static void main(String[] args) {// 创建一个只能装 String 的盒子Box<String> stringBox = new Box<>(); // 明确指定 T 为 StringstringBox.setItem("Hello Generics! <✨>");String message = stringBox.getItem(); // 直接就是 String,无需强转System.out.println(message);// stringBox.setItem(123); // 编译器报错❌!类型警察出动!// 创建一个只能装 Integer 的盒子Box<Integer> integerBox = new Box<>();integerBox.setItem(123);int number = integerBox.getItem(); // 直接就是 int (自动拆箱)System.out.println("Number in box: " + number);}
}
1.2.2 泛型方法 <🔧>

有时候,只是某个方法需要处理泛型,而不是整个类。

public class GenericMethodDemo {// 一个可以打印任何类型数组的泛型方法// 类型参数 <E> 声明在 static 和 返回值 void 之间public static <E> void printArray(E[] inputArray) {System.out.print("Array elements: [ ");for (E element : inputArray) { // element 的类型就是 ESystem.out.print(element + " ");}System.out.println("]");}public static void main(String[] args) {Integer[] intArray = { 1, 2, 3 };String[] stringArray = { "A", "B", "C" };// 调用时通常无需显式指定,编译器会自动推断System.out.println("Integer Array:");printArray(intArray); // 编译器推断 E 是 IntegerSystem.out.println("\nString Array:");printArray(stringArray); // 编译器推断 E 是 String}
}
1.2.3 有界类型参数 <T extends Number>

想让你的泛型更“挑剔”一点?比如,我的盒子只装数字相关的类型!

  • <T extends UpperBound>:告诉编译器,这里的 T 必须是 UpperBound 这个类,或者是它的子类。就像给盒子贴了个标签:“仅限数字!”🔢
  • 这让你可以在泛型代码内部安全地调用 UpperBound 类定义的方法。
// 一个只能装 Number 及其子类的盒子
class NumericBox<T extends Number> { // 关键字限定上界private T number;// ... setter/getter ...public double getDoubleValue() {// 因为 T 保证是 Number 或其子类,所以可以安全调用 Number 的方法return number.doubleValue();}
}public class BoundedTypeDemo {public static void main(String[] args) {NumericBox<Integer> intBox = new NumericBox<>();   // OK <✅>NumericBox<Float> floatBox = new NumericBox<>(); // OK <✅>// NumericBox<String> strBox = new NumericBox<>(); // 编译错误❌!String 不是 Number}
}
1.2.4 通配符 (Wildcards) <?> <❓>

通配符这东西,初看可能有点绕 <😵‍💫>,但它主要用在方法参数变量声明时,让你写出更灵活的代码,可以接收或引用“某种未知类型”的泛型

  • ? (无界通配符): “我啥都能接,但我不知道具体是啥”。List<?> list 可以指向 List<String>, List<Integer> 等等。但为了类型安全,你不能list添加任何元素(除了 null),通常只用于读取或调用Object的方法。
  • ? extends UpperBound (上界通配符): “我能接 UpperBound 及其所有子类型”。List<? extends Number> list 可以指向 List<Integer>, List<Double> 等。同样,不能往里添加元素(除了 null),主要用于安全地读取元素作为 UpperBound 类型(生产者场景)。
  • ? super LowerBound (下界通配符): “我能接 LowerBound 及其所有父类型”。List<? super Integer> list 可以指向 List<Integer>, List<Number>, List<Object>。你可以安全地list添加 Integer 或其子类的对象(消费者场景)。

何时深入? 当你开始大量使用泛型集合作为方法参数,并且希望方法能更通用地处理不同类型的集合时,就是研究通配符的好时机。

二、 枚举 (enum):定义常量集合的“专属俱乐部” 👑🚦

现在换个场景。如果你的程序需要表示一组固定的、有限的值,比如一周七天 📅、红绿灯状态 🚦、订单状态 (待付款、已付款、已发货…) 等等。

老办法可能是用 int 常量 (public static final int MONDAY = 1;) 或者 String 常量 (public static final String PENDING = "PENDING";)。但这种方式问题多多

  • 类型不安全🚫:一个期望星期几 int 的方法,你传个 100 进去,编译器根本不管
  • 可读性差 <😵‍💫>:代码里看到个数字 3,谁知道它代表星期三还是订单已发货?得翻文档去…
  • 没有命名空间 <🏷️>:常量名容易冲突。
  • 难以管理 <🛠️>:增加或修改常量可能涉及多处代码。

枚举 (enum) 就是来终结这种混乱的!它让你创建一个类型安全、含义清晰、管理方便常量集合

枚举的核心思想用一个专属的类型来代表一组有限的、命名的常量,并提供编译时安全检查

2.1 枚举闪光点

  1. 类型安全 <✅>:编译器强制你只能使用枚举中定义的常量。想给 DayOfWeek 类型的变量赋个 TrafficLight.RED?没门!编译错误
  2. 代码清晰、可读性爆表 <📖>if (order.getStatus() == OrderStatus.SHIPPED)if (order.getStatus() == 3) 不知道清晰多少倍!
  3. 代码更健壮、易维护 <🛠️>:常量集中管理。想加个“退款中”的状态?改 enum 就行。
  4. 不仅仅是常量 <💪>枚举本质上是特殊的class!它可以有构造方法、成员变量、普通方法,甚至可以实现接口!功能远超你的想象!

2.2 玩转枚举

2.2.1 基础款枚举 <🚦>

最简单的用法,就是定义一组常量。

// 定义交通信号灯枚举
public enum TrafficLight { // 使用 enum 关键字RED, YELLOW, GREEN // 常量列表,规范用大写
}public class BasicEnumSwitchDemo {public static void main(String[] args) {TrafficLight currentLight = TrafficLight.GREEN;// 在 switch 中使用枚举是绝配!<🎯>switch (currentLight) {case RED: // case 后面直接用常量名,不用写 TrafficLight.REDSystem.out.println("Stop! <✋>");break;case YELLOW:System.out.println("Caution! <⚠️>");break;case GREEN:System.out.println("Go! <✅>");break;// default 通常可以省略,因为枚举类型是有限的}// 遍历枚举所有常量System.out.println("\nAll light states:");for (TrafficLight light : TrafficLight.values()) { // values() 获取所有常量数组System.out.println("- " + light + " (ordinal: " + light.ordinal() + ")"); // ordinal() 是常量顺序}// 从字符串获取枚举常量TrafficLight lightFromString = TrafficLight.valueOf("RED"); // valueOf(),字符串必须精确匹配System.out.println("\nLight from string 'RED': " + lightFromString);}
}
2.2.2 进阶版枚举:带属性和方法 <👑><⚙️>

让你的常量“活”起来,拥有自己的数据和行为!

// 星期枚举,包含是否是工作日的属性和方法
public enum DayOfWeek {MONDAY(true),   // 调用构造方法传入 trueTUESDAY(true),WEDNESDAY(true),THURSDAY(true),FRIDAY(true),SATURDAY(false),  // 调用构造方法传入 falseSUNDAY(false);private final boolean isWeekday; // final 实例变量// 构造方法必须是 private (或包级私有)private DayOfWeek(boolean isWeekday) {this.isWeekday = isWeekday;}// 公共方法来获取属性public boolean isWeekday() {return isWeekday;}// 还可以定义其他方法public void printTypeOfDay() {if (isWeekday) {System.out.println(this.name() + " is a weekday. <💼>");} else {System.out.println(this.name() + " is part of the weekend! <🎉>");}}
}public class EnumWithMethodDemo {public static void main(String[] args) {DayOfWeek today = DayOfWeek.SATURDAY;System.out.println("Is today a weekday? " + today.isWeekday()); // falsetoday.printTypeOfDay(); // SATURDAY is part of the weekend! <🎉>System.out.println("\nChecking all days:");for (DayOfWeek day : DayOfWeek.values()) {day.printTypeOfDay();}}
}

三、 泛型 vs. 枚举 & 何时请哪位“大神”? 🤔⚖️

虽然都是好东西,但它们解决的问题完全不同:

  • 泛型出马:当你需要编写能处理各种不同(但类型未知)数据的通用代码时,比如 List<T>, Map<K,V>,或者一个通用的排序方法。目标是类型参数化编译时安全
  • 枚举出马:当你需要表示一个固定的、有限的、已知的常量集合时,比如星期、方向、状态、颜色等。目标是类型安全可读性清晰地表达意图

简单概括泛型处理不确定性 (类型);枚举处理确定性 (常量集合)。

四、总结 🏁✨

泛型枚举,就像给你的 Java 代码装上了安全带清晰的路标

  • 泛型 (<T>): 编译时就帮你挡住类型错误 <🛡️>,省去强制转换的麻烦 <✨>,让代码复用更容易 <🔄>。
  • 枚举 (enum): 把混乱的常量变成类型安全易读易维护的“专属俱乐部” <👑>,还能自带属性和方法 <💪>。

我的经验是:一旦你习惯了使用它们,就再也回不去那个充满ClassCastException魔法数字的“蛮荒时代”了!😄 它们是写出高质量现代 Java 代码的必备技能


五、练练手,检验成果!✏️🧠

光听不练等于零,动手试试吧!

⭐ 泛型应用 ⭐

  1. 创建一个泛型接口 Comparator<T>,包含一个方法 int compare(T o1, T o2),用于比较两个 T 类型的对象。然后创建一个实现类 StringLengthComparator 实现 Comparator<String>,用于比较字符串的长度。
  2. 编写一个泛型方法 <T> T findFirstMatch(List<T> list, Predicate<T> condition),该方法接收一个列表和一个条件(Predicate 是一个函数式接口,可以用 lambda 表达式 t -> boolean),返回列表中第一个满足条件的元素,如果找不到则返回 null。(提示:Predicate<T> 接口有一个 test(T t) 方法)

⭐ 枚举应用 ⭐

  1. 定义一个枚举 Size,包含常量 SMALL, MEDIUM, LARGE
  2. 为第 3 题的 Size 枚举添加一个int类型的 minWidth 字段和一个int类型的 maxWidth 字段,并提供构造方法和 getter。例如 SMALL(0, 50), MEDIUM(51, 100), LARGE(101, Integer.MAX_VALUE)

⭐ 概念理解 ⭐

  1. 什么是类型擦除?它是泛型实现的一部分吗?它对我们编写泛型代码有什么影响?(简单说明即可)
  2. 枚举类型可以extends(继承)另一个类吗?可以implements(实现)接口吗?

六、参考答案 ✅💡

⭐ 泛型应用答案 ⭐

1.Comparator<T> 接口与实现:

import java.util.Comparator; // Java 标准库已有 Comparator 接口,这里是模拟// 泛型接口定义
interface MyComparator<T> {int compare(T o1, T o2);
}// 实现类,比较字符串长度
class StringLengthComparator implements MyComparator<String> {@Overridepublic int compare(String s1, String s2) {// 返回负数表示 s1 < s2, 0 表示相等, 正数表示 s1 > s2return Integer.compare(s1.length(), s2.length());// 或者直接: return s1.length() - s2.length();}
}// 测试
public class ComparatorTest {public static void main(String[] args) {MyComparator<String> comparator = new StringLengthComparator();String str1 = "Java";String str2 = "Generics";int result = comparator.compare(str1, str2); // 比较 "Java" 和 "Generics" 的长度if (result < 0) {System.out.println("'" + str1 + "' is shorter than '" + str2 + "'");} else if (result > 0) {System.out.println("'" + str1 + "' is longer than '" + str2 + "'");} else {System.out.println("'" + str1 + "' and '" + str2 + "' have the same length.");}}
}

2.查找第一个匹配元素的泛型方法:

import java.util.List;
import java.util.Arrays;
import java.util.function.Predicate; // Java 8 的函数式接口public class FindFirstMatchDemo {public static <T> T findFirstMatch(List<T> list, Predicate<T> condition) {if (list == null || list.isEmpty() || condition == null) {return null;}for (T item : list) {if (condition.test(item)) { // 使用 Predicate 的 test 方法判断条件return item; // 找到第一个满足条件的,立即返回}}return null; // 遍历完都没找到}public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");// 查找第一个长度大于 4 的名字String longName = findFirstMatch(names, name -> name.length() > 4);System.out.println("First name longer than 4 chars: " + longName); // CharlieList<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);// 查找第一个偶数Integer firstEven = findFirstMatch(numbers, num -> num % 2 == 0);System.out.println("First even number: " + firstEven); // 2// 查找第一个大于 10 的数 (找不到)Integer greaterThan10 = findFirstMatch(numbers, num -> num > 10);System.out.println("First number > 10: " + greaterThan10); // null}
}

⭐ 枚举应用答案 ⭐

3.Size 枚举定义:

public enum Size {SMALL,MEDIUM,LARGE
}

4.带宽度范围的 Size 枚举:

public enum Size {SMALL(0, 50),MEDIUM(51, 100),LARGE(101, Integer.MAX_VALUE); // 使用 Integer.MAX_VALUE 表示无上限private final int minWidth;private final int maxWidth;private Size(int minWidth, int maxWidth) {this.minWidth = minWidth;this.maxWidth = maxWidth;}public int getMinWidth() {return minWidth;}public int getMaxWidth() {return maxWidth;}// 可以添加一个方法来判断某个宽度属于哪个 Sizepublic static Size getFittingSize(int width) {for (Size size : values()) {if (width >= size.getMinWidth() && width <= size.getMaxWidth()) {return size;}}// 理论上,如果定义完整,总能找到一个,但可以加个默认或抛异常return SMALL; // 或者抛出 IllegalArgumentException}
}// 使用示例
public class SizeDemo {public static void main(String[] args) {Size s = Size.MEDIUM;System.out.println("Medium min width: " + s.getMinWidth()); // 51System.out.println("Medium max width: " + s.getMaxWidth()); // 100int currentWidth = 75;Size fitting = Size.getFittingSize(currentWidth);System.out.println("Width " + currentWidth + " fits in size: " + fitting); // MEDIUM}
}

⭐ 概念理解答案 ⭐

5.类型擦除 (Type Erasure):是的,它是 Java 泛型实现的一部分。为了兼容没有泛型的老代码,Java 编译器在编译后会“擦除”掉大部分泛型的类型信息(类型参数会被替换成它们的上界,通常是 Object)。这意味着在运行时,JVM 其实并不知道 ArrayList<String>ArrayList<Integer> 的区别(它们都是 ArrayList)。
影响

  • 我们不能在运行时获取泛型参数的实际类型(如 list instanceof ArrayList<String>非法的)。
  • 不能创建泛型数组(如 new T[]不允许的,通常用 new Object[] 再强转)。
  • 不能实例化类型参数(如 new T()不行的,除非有特殊约束如 Class<T>)。
  • 静态上下文中不能使用类的类型参数。

枚举继承实现

  • 不能 extends 另一个 🚫:所有的枚举隐式地继承java.lang.Enum 类,由于 Java 是单继承的,所以枚举不能再继承其他类。
  • 可以 implements 接口 ✅:这是一个非常强大的特性!枚举可以实现一个或多个接口,使得不同的枚举常量可以有不同的行为实现(通常结合接口方法在每个常量内部匿名实现,或者定义一个统一的实现)。

恭喜你又解锁了 Java 的两个重要技能!泛型枚举在实际项目中应用非常广泛,多加练习,它们会让你的代码水平更上一层楼!🚀 如果觉得这篇笔记有帮助,点赞👍、收藏⭐、关注就是对我最好的肯定!谢谢大家!💖

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

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

相关文章

新能源行业供应链规划及集成计划报告(95页PPT)(文末有下载方式)

资料解读&#xff1a;《数字化供应链规划及集成计划现状评估报告》 详细资料请看本解读文章的最后内容。 该报告围绕新能源行业 XX 企业供应链展开&#xff0c;全面评估其现状&#xff0c;剖析存在的问题&#xff0c;并提出改进方向和关键举措&#xff0c;旨在提升供应链竞争力…

Centos 7 yum配置出现一下报错:

One of the configured repositories failed (CentOS-$releaserver-Base), and yum doesnt have enough cached data to continue. At this point the only safe thing yum can do is fail. There are a few ways to work "fix" this: 1.解决CentOS Yum Repositor…

Redis 常见问题深度剖析与全方位解决方案指南

Redis 是一款广泛使用的开源内存数据库&#xff0c;在实际应用中常会遇到以下一些常见问题&#xff1a; 1.内存占用问题 问题描述&#xff1a;随着数据量的不断增加&#xff0c;Redis 占用的内存可能会超出预期&#xff0c;导致服务器内存不足&#xff0c;影响系统的稳定性和…

HOOK上瘾思维模型——AI与思维模型【88】

一、定义 HOOK上瘾思维模型是一种通过设计一系列的触发&#xff08;Trigger&#xff09;、行动&#xff08;Action&#xff09;、奖励&#xff08;Reward&#xff09;和投入&#xff08;Investment&#xff09;环节&#xff0c;来促使用户形成习惯并持续使用产品或服务的思维框…

【playwright】内网离线部署playwright

背景&#xff1a;安装好python3.9后&#xff0c;由于内网无法使用pip安装playwright&#xff0c;多方收集资料&#xff0c;终于部署完成&#xff0c;现汇总如下&#xff1a; 1、playwright需要python3.7以上的版本&#xff0c;如果低于这个版本先要将python解释器升级 2、在可…

Unity动态列表+UniTask异步数据请求

Unity动态列表UniTask异步数据请求 很久没有写东西了。最近有一个需求&#xff0c;在Unity项目里&#xff0c;有几个比较长的列表&#xff0c;经历了一翻优化&#xff0c;趁这几日闲暇&#xff0c;记录下来&#xff0c;给自己留个笔记&#xff0c;也送给有缘之人共同探讨吧。 …

pandas读取Excel数据(.xlsx和.xls)到treeview

对于.xls文件&#xff0c;xlrd可能更合适&#xff0c;但需要注意新版本的xlrd可能不支持xlsx&#xff0c;不过用户可能同时需要处理两种格式&#xff0c;所以可能需要结合openpyxl和xlrd&#xff1f;或者直接用pandas&#xff0c;因为它内部会处理这些依赖。 然后&#xff0c;…

2025年Jetpack Compose集成网络请求库的完整实施方案

Compose中集成网络请求库&#xff0c;网络请求现在Retrofit是最流行的。 首先在Compose中如何进行网络请求&#xff0c;而不仅仅是集成库。因为Compose本身是UI框架&#xff0c;网络请求其实还是通过ViewModel或者Repository来处理&#xff0c;然后通过状态管理来更新UI。所以…

机器视觉开发-摄像头扫描二维码

以下是使用Python和OpenCV实现摄像头扫描二维码的最简单示例&#xff1a; import cv2 from pyzbar import pyzbar# 打开摄像头 cap cv2.VideoCapture(0)print("正在扫描二维码... (按 q 键退出)")while True:# 读取摄像头帧ret, frame cap.read()if not ret:print…

Seata服务端回滚事务核心源码解析

文章目录 前言一、doGlobalRollback3.1、changeGlobalStatus3.2、doGlobalRollback 前言 本篇介绍Seata服务端接收到客户端TM回滚请求&#xff0c;进行处理并且驱动所有的RM进行回滚的源码。 一、doGlobalRollback doGlobalRollback是全局回滚的方法&#xff1a;   首先依旧…

新闻客户端案例的实现,使用axios获取数据并渲染页面,路由传参(查询参数,动态路由),使用keep-alive实现组件缓存

文章目录 0.页面要求1.功能要求2.开始路由配置2.1.嵌套二级路由如何配置?2.2.路由重定向,NotFound页面,去除"#"号 3.实现底部导航栏的高亮效果4.渲染首页:使用axios请求数据5.路由传参5.1.回顾:查询参数传参或者动态路由传参5.2.具体代码 6.渲染详情页7.解决请求过程…

文件操作--文件包含漏洞

本文主要内容 脚本 ASP、PHP、JSP、ASPX、Python、Javaweb --# 各种包含函数 检测 白盒 代码审计 黑盒 漏扫工具、公开漏洞、手工看参数值及功能点 类型 本地包含 有限制、无限制 远程包含 无限制、有限制…

ActiveMQ 性能优化与网络配置实战(二)

五、性能优化实战 5.1 基础配置调整 5.1.1 增加并发消费者 在 ActiveMQ 中&#xff0c;增加并发消费者是提高消息处理效率的重要手段之一。通过配置多个消费者并行处理消息&#xff0c;可以充分利用系统资源&#xff0c;加快消息的消费速度&#xff0c;从而提高系统的整体吞…

C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 17)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 二…

贪心算法精解(Java实现):从理论到实战

一、贪心算法概述 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下最优决策的算法策略。它通过局部最优选择来达到全局最优解&#xff0c;具有高效、简洁的特点。 核心特点&#xff1a; 局部最优选择&#xff1a;每一步都做出当前看…

深度学习框架:PyTorch使用教程 !!

文章目录 一、PyTorch框架简介 1.1 什么是PyTorch 1.2 PyTorch的优势 二、从入门到精通的PyTorch使用教程 2.1 入门阶段 2.1.1 环境安装与配置 2.1.2 Tensor基础操作 2.1.3 自动求导&#xff08;Autograd&#xff09; 2.1.4 构建神经网络&#xff08;nn模块&#xff09; 2.1.5 …

系统架构设计师:设计模式——创建型设计模式

一、创建型设计模式 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给另一个对象。 随着系统演化得越来越依赖于对象复合而不是类…

Dinero.js - 免费开源的 JavaScript 货币处理工具库,完美解决 JS 浮点数精度丢失问题

今天介绍一个在前后端处理货币的工具库&#xff0c;logo 很可爱&#xff0c;是一只蓝色的招财小猫。 本文封面图底图来自免费 AI 图库 StockCake。 Dinero.js 是一个用于货币计算的 JavaScript 工具库&#xff0c;解决开发者在金融、电商、会计等场景中处理货币时的精度丢失、…

HNUST湖南科技大学-嵌入式考试选择题题库(109道纠正详解版)

HNUST嵌入式选择题题库 1.下面哪点不是嵌入式操作系统的特点。(B) A.内核精简 B.功能强大 C.专用性强 D.高实时性 解析&#xff1a; 嵌入式操作系统特点是内核精简、专用性强、高实时性&#xff0c;而"功能强大"通常指的是通用操作系统&#x…

【工具】Windows批量文件复制教程:用BAT脚本自动化文件管理

一、引言 在日常开发与部署过程中&#xff0c;文件的自动化复制是一个非常常见的需求。无论是在构建过程、自动部署&#xff0c;还是备份任务中&#xff0c;开发者经常需要将某个目录中的 DLL、配置文件、资源文件批量复制到目标位置。相比使用图形界面的复制粘贴操作&#xf…