告别冗长代码:Java Lambda 表达式如何简化你的编程
在现代软件开发中,高效和简洁的代码变得越来越重要。Java作为一门成熟而广泛使用的编程语言,一直在不断进化,以满足开发者的需求。Java 8的推出标志着一次重要的飞跃,其中最引人注目的特性之一便是Lambda表达式。
Lambda表达式为Java带来了函数式编程的灵活性,使得代码不仅更加简洁,还大大提升了可读性和维护性。不再需要冗长的匿名类,开发者可以用更少的代码完成更多的功能。对于那些致力于编写高效、简洁代码的开发者来说,掌握Lambda表达式是不可或缺的技能。
在本篇文章中,我们将深入探讨Java的Lambda表达式,揭示它的强大功能和应用场景。无论你是Java的初学者,还是有多年经验的老手,这篇文章都将带你领略Lambda表达式的魅力,帮助你在编程之旅中迈上新的台阶。
文章目录
- 1、Lambda表达式概述
- 1.1、Lambda表达式的简介
- 1.2、Lambda 表达式的基本语法
- 1.3、Lambda 表达式的基础示例
- 1.4、Lambda表达式的要求
- 2、函数式接口
- 2.1、什么是函数式接口
- 2.2、函数式接口的定义
- 2.3、主要的函数式接口
- 2.3.1、接口 `Predicate<T>`
- 2.3.2、接口 `Consumer<T>`
- 2.3.3、接口 `Function<T, R>`
- 2.3.4、接口 `Supplier<T>`
- 2.3.5、接口 `BiConsumer<T, U>`
- 2.3.6、接口 `BiFunction<T, U, R>`
- 2.3.7、接口 `UnaryOperator<T>`:
- 2.3.8、接口 `BinaryOperator<T>`:
- 3、Lambda 方法引用
- 3.1、Lambda 方法引用的介绍
- 3.2、静态方法引用
- 3.3、实例方法引用
- 3.4、特定类型的任意对象的实例方法引用
- 3.5、构造器引用
- 4、Lambda 变量捕获
- 4.1、变量捕获的类型
- 4.2、什么是 Effectively Final?
- 4.3、示例:捕获局部变量
- 4.4、不可以捕获的情况
- 4.5、捕获实例变量
- 5、Lambda 在集合当中的使用
- 5.1、`Collection` 新增接口
- 5.2、`List` 新增接口
- 5.3、`Set` 新增接口
- 5.4、`Map` 新增接口
1、Lambda表达式概述
1.1、Lambda表达式的简介
Java(SE)8 于 2014 年 3 月发布,引入了多个改进特性,其中 Lambda 表达式(Lambda expression,也可称为闭包(Closure))是最受欢迎的新特性之一。
Lambda 表达式允允许把函数作为一个方法的参数,允许在方法中传递代码块,从而实现更加灵活的编程方式。Lambda 表达式可以简化代码,减少样板代码的出现,并且使代码更加易读和易于维护。
Lambda 表达式允许我们通过表达式来代替功能接口。Lambda 表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
Lambda 表达式为 Java 添加了函数式编程的能力,简化了代码,使得编写简洁的代码成为可能。这一特性特别适用于对集合进行操作的场景。
1.2、Lambda 表达式的基本语法
Lambda 表达式基本上是一个简洁的表示匿名函数的方法,它不需要像匿名类那样繁琐。Lambda 表达式的语法如下:
code(parameters) -> expression 或 (parameters) -> { statements; }

其中 Lambda 表达式的三个组成部分:
- 参数列表(
parameters):类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可不声明而由 JVM 隐含的推断。另外如果只有一个参数,圆括号也可以省略; - 箭头(->):连接参数列表和 Lambda 主体,可理解为 “被用于” 的意思;
- Lambda 主体(
expression或 {statements;}):可以是表达式也可以代码块,是函数式接口里方法的实现。①、expression:表达式,当 Lambda 体只有一条语句时可以是一个表达式或一个单独的语句;②、statements:代码块,如果 Lambda 体包含多条语句,需要用花括号括起来。③、无论是表达式还是代码块,都可以返回一个值或者什么都不反回。
1.3、Lambda 表达式的基础示例
假设我们有一个字符串列表,我们想要对其排序。使用 Lambda 表达式前后的代码对比如下:
使用传统方法(匿名内部类):
List<String> names = Arrays.asList("Peter", "Anna", "Mike", "Xenia");Collections.sort(names, new Comparator<String>() {public int compare(String a, String b) {return a.compareTo(b);}
});
匿名内部类: 这里 new Comparator<String>() {...} 创建了一个 Comparator<String> 的匿名实现类。匿名内部类是没有类名的类,直接用其父类或要实现的接口作为其类型。
使用 Lambda 表达式:
List<String> names = Arrays.asList("Peter", "Anna", "Mike", "Xenia");Collections.sort(names, (String a, String b) -> {return a.compareTo(b);
});--- 或者更简洁Collections.sort(names, (a, b) -> a.compareTo(b));
1.4、Lambda表达式的要求
虽然说,Lambda 表达式可以在⼀定程度上简化接口的实现。但是,并不是所有的接口都可以使用 Lambda 表达式来简洁实现的。
Lambda 表达式毕竟只是⼀个匿名方法。当实现的接口中的方法过多或者多少的时候,Lambda 表达式都是不适用的。
Lambda 表达式,只能实现函数式接口。
2、函数式接口
2.1、什么是函数式接口
在 Java 中,函数式接口(Functional Interface)是指具有单一抽象方法的接口,但它可以有多个默认(default)或静态(static)方法。Java 8 引入了这个概念,主要是为了支持 Lambda 表达式,同时保持对老代码的兼容性。
函数式接口的特性:
- 单一抽象方法:这是函数式接口的核心特征,它意味着该接口中只有一个没有实现的方法;
- 默认方法:Java 8 允许在接口中实现方法,这些方法被称为默认方法。默认方法不影响接口的"函数式接口"状态,因为它们不是抽象的;
- 静态方法:接口还可以包含静态方法。这些方法同样不影响接口的函数式接口状态,因为静态方法也是具体实现的。
函数式接口提供了一种将功能逻辑作为数据传递的方式,极大地增强了 Java 在编写高效且简洁代码方面的能力。随着 Java 版本的迭代,函数式编程已成为开发中不可或缺的工具。
2.2、函数式接口的定义
在 Java 中,函数式接口通常通过 @FunctionalInterface 注解来表示。这个注解不是必需的,但它可以帮助编译器检查所标注的接口是否满足函数式接口的条件。标准的定义如下:
@FunctionalInterface
public interface MyFunctionalInterface {void execute();
}
2.3、主要的函数式接口
Java 8 引入了 java.util.function 包,这个包中定义了一系列的内建函数式接口,极大地方便了函数式编程的实践,特别是与 Lambda 表达式的结合使用。
2.3.1、接口 Predicate<T>
用途:Predicate<T> 接口定义一个参数的方法,返回布尔值。这通常用于判断或过滤数据。
方法签名:boolean test(T t);
示例:使用 Predicate<T> 过滤一个 List<String>,移除不符合条件的元素。
List<String> names = Arrays.asList("Peter", "Anna", "Mike", "Xenia");
// 移除以"M"开头的名字
names.removeIf(name -> name.startsWith("M"));
2.3.2、接口 Consumer<T>
用途:Consumer<T> 接口定义单一输入参数的 accept 方法,不返回任何结果(void 返回类型),常用于在对象上执行某些操作,如打印数据。
方法签名:void accept(T t);
示例:使用 Consumer<T> 打印 List 中的每个元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(number -> System.out.println(number));
2.3.3、接口 Function<T, R>
用途:Function<T, R> 接口定义一个接受一个参数并产生结果的方法,常用于映射或转换数据。
方法签名:R apply(T t);
示例:将字符串转换为其长度。
List<String> names = Arrays.asList("Peter", "Anna", "Mike", "Xenia");
List<Integer> nameLengths = names.stream().map(name -> name.length()).collect(Collectors.toList());
2.3.4、接口 Supplier<T>
用途:Supplier<T> 不接受任何参数但返回一个值,并且这个值的类型是泛型 T。它常用于延迟生成或提供值的场景。
方法签名:T get();
示例:提供当前时间的字符串格式。
Supplier<String> currentTime = () -> new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Current Time: " + currentTime.get());
2.3.5、接口 BiConsumer<T, U>
用途:接受两个输入参数,无返回结果,用于两元素的操作。
方法签名:void accept(T t, U u);
示例:打印两个参数的和。
BiConsumer<Integer, Integer> add = (a, b) -> System.out.println("Sum: " + (a + b));
// 输出 Sum: 8
add.accept(5, 3);
2.3.6、接口 BiFunction<T, U, R>
用途:接受两个输入参数,返回一个结果,用于两元素的操作。
方法签名:R apply(T t, U u);
示例:计算两个参数的和。
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
// 计算 1+2 的结果
Integer sum = add.apply(1, 2);
2.3.7、接口 UnaryOperator<T>:
用途:一种特殊类型的 Function,输入参数类型和返回类型相同。
方法:T apply(T t);
示例:计算参数的平方并返回。
UnaryOperator<Integer> square = x -> x * x;
Integer result = square.apply(5);
2.3.8、接口 BinaryOperator<T>:
用途:一种特殊类型的 BiFunction,其中两个输入参数和返回类型都相同。
方法:T apply(T t1, T t2);
示例:计算两个参数的积并返回。
BinaryOperator<Integer> multiply = (a, b) -> a * b;
Integer product = multiply.apply(5, 3);
3、Lambda 方法引用
3.1、Lambda 方法引用的介绍
在 Java 中,方法引用是一种简化 lambda 表达式的写法,特别是当 lambda 表达式只是直接调用一个已存在的方法时。方法引用提供了一种更清晰、更简洁的方式来引用直接已存在的方法或构造器。
方法引用有四种主要的类型:
- 静态方法引用(ClassName::methodName);
- 实例方法引用(instance::methodName);
- 特定类型的任意对象的实例方法引用(ClassName::methodName);
- 构造器引用(ClassName::new)
3.2、静态方法引用
如果函数式接口的实现通过调用一个静态方法来完成,可以使用静态方法引用。
示例:
假设我们有以下静态方法:
public class MathOperations {public static int multiplyByTwo(int i) {return i * 2;}
}
我们可以这样使用方法引用替代相应的 lambda 表达式:
Function<Integer, Integer> timesTwo = MathOperations::multiplyByTwo;
// 输出 10
System.out.println(timesTwo.apply(5));
3.3、实例方法引用
当目标引用是一个实例的方法时,可以使用实例方法引用。
示例:
假设有一个非静态方法:
public class Printer {public void printUpperCase(String s) {System.out.println(s.toUpperCase());}
}
使用实例方法引用:
Printer printer = new Printer();
Consumer<String> printUpper = printer::printUpperCase;
// 输出 HELLO
printUpper.accept("hello");
3.4、特定类型的任意对象的实例方法引用
如果方法引用是针对特定类型的任意对象,可以使用 ClassName::methodName。
示例:
Function<String, String> upperFunct = String::toUpperCase;
// 输出 HELLO
System.out.println(upperFunct.apply("hello"));
这里,我们引用了 String 类的 toUpperCase 方法。
3.5、构造器引用
构造器引用与方法引用类似,但它调用的是类的构造器。
示例:
假设我们有以下类:
public class Person {private String name;public Person(String name) {this.name = name;}@Overridepublic String toString() {return "Person{name='" + name + "'}";}
}
使用构造器引用:
Function<String, Person> personCreator = Person::new;
Person p = personCreator.apply("John Doe");// 输出 Person{name='John Doe'}
System.out.println(p);
4、Lambda 变量捕获
Lambda 表达式与匿名内部类相似,它们都可以访问"外围"作用域中的变量。这种访问外围变量的行为称为"变量捕获"。
4.1、变量捕获的类型
在 Lambda 表达式中,可以捕获两种类型的变量:
-
实例变量和静态变量:Lambda 表达式内部可以自由使用实例变量和静态变量而不受任何限制,这些变量可以自由地被读取或修改;
-
局部变量:可以捕获外围方法的局部变量,但这些局部变量必须是事实上的最终变量(effectively final),即这些变量在初始化后不会再为它们赋新值。
4.2、什么是 Effectively Final?
一个变量如果被声明为 final,那么它就是最终变量。即使变量没有被声明为 final,但在初始化后从未改变过,那么这个变量也是事实上的最终变量。从 Java 8 开始,这样的未声明为 final 的变量也可以在 Lambda 表达式中被捕获。
4.3、示例:捕获局部变量
public class LambdaCaptureExample {public static void main(String[] args) {int num = 10;// Effectively final variableRunnable r = () -> System.out.println(num);// 输出 10r.run();}
}
在这个例子中,变量 num 虽然没有被声明为 final,但在初始化之后没有再改变,所以它是事实上的最终变量,可以在 Lambda 表达式中被安全捕获。
4.4、不可以捕获的情况
如果尝试在 Lambda 表达式中捕获一个不是事实上的最终变量,编译器将会报错:
public class LambdaCaptureExample {public static void main(String[] args) {int num = 10;num = 20; // 修改变量,使其不再是 effectively finalRunnable r = () -> System.out.println(num); // 编译错误r.run();}
}
因为 num 在初始化后被修改,它不是一个事实上的最终变量,因此不能被 Lambda 表达式捕获。
4.5、捕获实例变量
实例变量与静态变量不需要是事实上的最终变量,它们可以在 Lambda 表达式内部被修改:
public class LambdaCaptureExample {private static int staticNum = 5;private int instanceNum = 5;public void test() {Runnable r = () -> {// 直接修改静态变量staticNum++; // 直接修改实例变量instanceNum++;// 输出 12System.out.println(staticNum + instanceNum); };r.run();}public static void main(String[] args) {new LambdaCaptureExample().test();}
}
5、Lambda 在集合当中的使用
Java 8 在 Collection、List、Set、和 Map 接口中引入了多种新方法,这些方法大都利用 Lambda 表达式来提高编程效率和简化代码。
下面是这些接口中新增方法的详细介绍:
5.1、Collection 新增接口
Collection 接口是 List 和 Set 接口的父接口,因此在 Collection 中添加的方法也会影响到这两个接口。以下是新增的几个重要方法:
①、forEach(Consumer<? super T> action) 对每个元素执行指定的动作。这是内部迭代的一种形式,可以替代外部迭代(即使用 for-each 循环)
collection.forEach(System.out::println);
②、stream() 返回集合的顺序 Stream 表达形式,可以进行更复杂的聚合操作
collection.stream().filter(e -> e.startsWith("A")).forEach(System.out::println);
③、parallelStream() 返回集合的并行 Stream 表达形式,用于并行处理集合元素,适用于数据量大时的场景
collection.parallelStream().filter(e -> e.startsWith("A")).forEach(System.out::println);
④、removeIf(Predicate<? super E> filter) 根据指定的条件(Predicate 表达式)删除元素
// 删除所有空元素
collection.removeIf(e -> e.isEmpty());
⑤、spliterator() 提供了一种创建可分割迭代器(Spliterator)的方法,适用于 Stream 的并行分解
Spliterator<T> spliterator = collection.spliterator();
5.2、List 新增接口
除了继承自 Collection 接口的方法外,List 接口特有的新增方法主要包括:
①、sort(Comparator<? super E> c) 根据指定的比较器对列表进行排序,此方法直接修改原列表
list.sort(Comparator.naturalOrder());
②、replaceAll(UnaryOperator<E> operator) 根据指定的函数应用运算,替换每个元素
// 将所有字符串元素转换为大写
list.replaceAll(String::toUpperCase);
5.3、Set 新增接口
Set 接口没有特别的新增方法,它继承了 Collection 接口的所有新增方法,这包括 forEach, stream, parallelStream, removeIf, 和 spliterator。
5.4、Map 新增接口
Map 接口在 Java 8 中增加了一系列非常有用的方法来简化常见的任务:
①、forEach(BiConsumer<? super K, ? super V> action) 对每个键值对执行指定的操作
map.forEach((key, value) -> System.out.println(key + ": " + value));
②、replaceAll(BiFunction<? super K, ? super V, ? extends V> function) 将每个元素替换为函数的结果
map.replaceAll((key, value) -> value.toUpperCase());
③、computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) 如果键对应的值为 null,则尝试计算新的映射,并插入到 Map 中
map.computeIfAbsent("key", k -> "New " + k);
④、computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) 如果键存在,则使用给定的重新映射函数计算其值
map.computeIfPresent("key", (k, v) -> v + " Updated");
⑤、compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) 对键进行重新计算,无论原来是否存在
map.compute("key", (k, v) -> (v == null) ? "New Value" : v + " Computed");
⑥、merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) 将键映射到给定值和当前值(如果已存在)的重新映射结果
map.merge("key", "New Value", (v1, v2) -> v1 + ", " + v2);
这些方法使得对集合进行操作更加灵活和强大,特别是在需要对集合进行批量操作、计算或条件更新时。通过这些工具,Java的集合库更加贴近现代编程需求,使得代码不仅更简洁,而且性能也有所提升。
相关文章:
告别冗长代码:Java Lambda 表达式如何简化你的编程
在现代软件开发中,高效和简洁的代码变得越来越重要。Java作为一门成熟而广泛使用的编程语言,一直在不断进化,以满足开发者的需求。Java 8的推出标志着一次重要的飞跃,其中最引人注目的特性之一便是Lambda表达式。 Lambda表达式为J…...
不同生成式AI模型的优缺点(GAN,VAE,FLOW)
不同生成式人工智能模型的优缺点 近年来,生成式 AI 模型因其能够创建新的原创内容而备受关注。这些模型旨在生成类似于给定训练数据集的数据,从而产生逼真且富有创意的输出。了解不同类型的生成式 AI 模型及其优缺点对于研究人员、开发人员和用户做出明…...
VMware ESXi 8.0U2c macOS Unlocker OEM BIOS 集成网卡驱动 Marvell AQC 网卡定制版
VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS 集成网卡驱动 Marvell AQC 网卡定制版 VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U2 集成驱动版,在个人电脑上运行企业级工作负载 请访问原文链…...
SpringCloud Consul基础入门与使用实践总结
【1】Consul简介 官网地址:https://www.consul.io/intro/index.html 下载地址:https://www.consul.io/downloads.html 中文文档:https://www.springcloud.cc/spring-cloud-consul.html ① 基础概念 Consul 是一套开源的分布式服务发现和…...
pdf拆分成有图和无图的pdf(方便打印)
pdf拆分成有图和无图的pdf(方便打印) 原因 打印图片要彩印,每次都要手动弄,打印的时候很麻烦; 随着打印次数的增加,时间就越来越多 为解决此问题,使用python写一个exe解决这个问题 历程 找一个python的GUI界面找到 t…...
通用树查找算法
想要一个树形控件来显示数据,却发现Racket的GUI库竟然没有提供这个控件。既然没有,那就自己手搓一个吧。没想到,在做这个控件中竟然有了新发现! 树形控件有一个功能是查找树中指定的节点。这就是接下来的故事的起点。 1 找外援 不…...
Flutter 中的 TableCell 小部件:全面指南
Flutter 中的 TableCell 小部件:全面指南 Flutter 是一个功能强大的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的丰富组件库中,TableCell 是一个用于创建表格单元格的组件…...
clickhouse学习笔记(一)入门与安装
目录 一 、入门 简介 核心特性包括 1.1 列式存储 1.2 原生压缩 1.3 向量化执行引擎 1.4 DBMS 功能 1.5 分布式处理 1.6 高吞吐写入能力 1.7 实时分析 1.8 SQL支持 1.9 高度可扩展 1.10 数据分区与线程级并行 1.11 应用场景 1.12 不适用场景 二、ClickHouse单机版…...
【JavaEE精炼宝库】多线程(4)深度理解死锁、内存可见性、volatile关键字、wait、notify
目录 一、死锁 1.1 出现死锁的常见场景: 1.2 产生死锁的后果: 1.3 如何避免死锁: 二、内存可见性 2.1 由内存可见性产生的经典案例: 2.2 volatile 关键字: 2.2.1 volatile 用法: 2.2.2 volatile 不…...
使用Ollama+OpenWebUI部署和使用Phi-3微软AI大模型完整指南
🏡作者主页: 点击! 🤖AI大模型部署与应用专栏:点击! ⏰️创作时间:2024年6月6日23点50分 🀄️文章质量:96分 欢迎来到Phi-3模型的奇妙世界!Phi-3是由微软…...
k8s的ci/cd实践之旅
书接上回k8s集群搭建完毕,来使用它强大的扩缩容能力帮我们进行应用的持续集成和持续部署,整体的机器规划如下: 1.192.168.8.156 搭建gitlab私服 docker pull gitlab/gitlab-ce:latest docker run --detach --hostname 192.168.8.156 --publ…...
笔记96:前馈控制 + 航向误差
1. 回顾 对于一个 系统而言,结构可以画作: 如果采用 这样的控制策略,结构可以画作:(这就是LQR控制) 使用LQR控制器,可以通过公式 和 构建一个完美的负反馈系统; a a 但是有上…...
延时任务工具类
自定义工具类 package com.sxfoundation.task;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.task.TaskRejectedException; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.spri…...
springboot下载grpc编译文件,报错缺少protoc-gen-grpc-java:1.34.1:exe不存在
报错如图所示 [ERROR] Then, install it using the command: [ERROR] mvn install:install-file -DgroupIdio.grpc -DartifactIdprotoc-gen-grpc-java -Dversion1.34.1 -Dclassifierwindows-x86_64 -Dpackagingexe -Dfile/path/to/file [ERROR] [ERROR] Alternatively, if yo…...
【面试干货】 非关系型数据库(NoSQL)与 关系型数据库(RDBMS)的比较
【面试干货】 非关系型数据库(NoSQL)与 关系型数据库(RDBMS)的比较 一、引言二、非关系型数据库(NoSQL)2.1 优势 三、关系型数据库(RDBMS)3.1 优势 四、结论 💖The Begin…...
JAVA学习-练习试用Java实现“简化路径”
问题: 给定一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 / 开头),请将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中,一个点(.)表示当前目录本身…...
STM32——ADC篇(ADC的使用)
一、ADC的介绍 1.1什么是ADC ADC(Analogto-Digital Converter)模拟数字转换器,是将模拟信号转换成数字信号的一种外设。比如某一个电阻两端的是一个模拟信号,单片机无法直接采集,此时需要ADC先将短租两端的电…...
(文章复现)基于主从博弈的售电商多元零售套餐设计与多级市场购电策略
参考文献: [1]潘虹锦,高红均,杨艳红,等.基于主从博弈的售电商多元零售套餐设计与多级市场购电策略[J].中国电机工程学报,2022,42(13):4785-4800. 1.摘要 随着电力市场改革的发展,如何制定吸引用户选择的多类型零售套餐成为提升售电商利润的研究重点。为…...
深度评价GPT-4o:探索人工智能的新里程碑
在人工智能领域,OpenAI的GPT系列自推出以来就备受瞩目。GPT-4o作为该系列的最新版本,无疑是迄今为止最为强大的一代。它不仅在技术性能上有了质的飞跃,而且在应用的广泛性和深度上都展现出了惊人的潜力。本文将从版本对比、技术能力、使用体验…...
Linux命令篇(六):vi/vim专项
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝您生活愉快! 文章目录 一、什么是vim二…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...
