stream流和方法引用
1.Stream流
1.1体验Stream流【理解】
-
案例需求
按照下面的要求完成集合的创建和遍历
- 创建一个集合,存储多个字符串元素
- 把集合中所有以"张"开头的元素存储到一个新的集合
- 把"张"开头的集合中的长度为3的元素存储到一个新的集合
- 遍历上一步得到的集合
-
原始方式示例代码
public class MyStream1 {public static void main(String[] args) {//集合的批量添加ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));//遍历list1把以张开头的元素添加到list2中。ArrayList<String> list2 = new ArrayList<>();for (String s : list1) {if(s.startsWith("张")){list2.add(s);}}//遍历list2集合,把其中长度为3的元素,再添加到list3中。ArrayList<String> list3 = new ArrayList<>();for (String s : list2) {if(s.length() == 3){list3.add(s);}}for (String s : list3) {System.out.println(s);} } } -
使用Stream流示例代码
public class StreamDemo {public static void main(String[] args) {//集合的批量添加ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));//Stream流list.stream().filter(name -> name.startsWith("张")).filter(name -> name.length() == 3).forEach(name -> System.out.println(name));} } -
Stream流的好处
- 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
- Stream流把真正的函数式编程风格引入到Java中
- 代码简洁
1.2Stream流的常见生成方式【应用】
-
Stream流的思想

-
Stream流的三类方法
- 获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
- 中间方法
- 流水线上的操作
- 一次操作完毕之后,还可以继续进行其他操作
- 终结方法
- 一个Stream流只能有一个终结方法
- 是流水线上的最后一个操作
- 获取Stream流
-
生成Stream流的方式
-
Collection体系集合
使用默认方法stream()生成流,
default Stream<E> stream() -
Map体系集合
把Map转成Set集合,间接的生成流 -
数组
通过Arrays中的静态方法stream生成流 -
同种数据类型的多个数据
通过Stream接口的
静态方法of(T... values)生成流
-
-
代码演示
public class StreamDemo {public static void main(String[] args) {//Collection体系的集合可以使用默认方法stream()生成流List<String> list = new ArrayList<String>();Stream<String> listStream = list.stream();Set<String> set = new HashSet<String>();Stream<String> setStream = set.stream();//Map体系的集合间接的生成流Map<String,Integer> map = new HashMap<String, Integer>();Stream<String> keyStream = map.keySet().stream();Stream<Integer> valueStream = map.values().stream();Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();//数组可以通过Arrays中的静态方法stream生成流String[] strArray = {"hello","world","java"};Stream<String> strArrayStream = Arrays.stream(strArray);//同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");Stream<Integer> intStream = Stream.of(10, 20, 30);} }
1.3Stream流中间操作方法【应用】
-
概念
中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作 -
常见方法
方法名 说明 Stream filter(Predicate predicate) 用于对流中的数据进行过滤 Stream limit(long maxSize) 获取前几个元素 Stream skip(long n) 跳过前几个元素 static Stream concat(Stream a, Stream b) 合并a和b两个流为一个流 Stream distinct() 元素去重,依赖(hashCode和equals方法) Stream map(Function<T,R> mapper) 转换流中的数据类型 -
filter代码演示public class MyStream3 {public static void main(String[] args) { // Stream<T> filter(Predicate predicate):过滤 // Predicate接口中的方法 boolean test(T t):对给定的参数进行判断,返回一个布尔值ArrayList<String> list = new ArrayList<>();list.add("张三丰");list.add("张无忌");list.add("张翠山");list.add("王二麻子");list.add("张良");list.add("谢广坤");//filter方法获取流中的 每一个数据.//而test方法中的s,就依次表示流中的每一个数据.//我们只要在test方法中对s进行判断就可以了.//如果判断的结果为true,则当前的数据留下//如果判断的结果为false,则当前数据就不要.list.stream().filter(new Predicate<String>() {@Overridepublic boolean test(String s) {boolean result = s.startsWith("张");return result;}}).forEach(s-> System.out.println(s));//因为Predicate接口中只有一个抽象方法test所以我们可以使用lambda表达式来简化list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));} } -
limit&skip代码演示public class StreamDemo02 {public static void main(String[] args) {//创建一个集合,存储多个字符串元素ArrayList<String> list = new ArrayList<String>();list.add("林青霞");list.add("张曼玉");list.add("王祖贤");list.add("柳岩");list.add("张敏");list.add("张无忌");//需求1:取前3个数据在控制台输出list.stream().limit(3).forEach(s-> System.out.println(s));System.out.println("--------");//需求2:跳过3个元素,把剩下的元素在控制台输出list.stream().skip(3).forEach(s-> System.out.println(s));System.out.println("--------");//需求3:跳过2个元素,把剩下的元素中前2个在控制台输出list.stream().skip(2).limit(2).forEach(s-> System.out.println(s));} } -
concat&distinct代码演示public class StreamDemo03 {public static void main(String[] args) {//创建一个集合,存储多个字符串元素ArrayList<String> list = new ArrayList<String>();list.add("林青霞");list.add("张曼玉");list.add("王祖贤");list.add("柳岩");list.add("张敏");list.add("张无忌");//需求1:取前4个数据组成一个流Stream<String> s1 = list.stream().limit(4);//需求2:跳过2个数据组成一个流Stream<String> s2 = list.stream().skip(2);//需求3:合并需求1和需求2得到的流,并把结果在控制台输出Stream.concat(s1,s2).forEach(s-> System.out.println(s));//需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));} } -
map代码演示public class OptionalDemo {public static void main(String[] args) {List<String> list = new ArrayList<>();Collections.addAll(list, "张无忌-15", "周芷若-14", "张强-20", "张三丰-100", "张翠山-40", "张良-35", "王二麻子-37", "谢广坤-41");// 只获取集合中的年龄并进行打印 string->int//第一个类型:流中原本的数据类型,这里是指String//第二个类型:要转成的类型,这里是指int//apply的形参s:一次代表流里面的每一个数据//返回值:表示转换之后的数据list.stream().map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {String[] arr = s.split("-");String ageString = arr[1];int age = Integer.parseInt(ageString);return age;}}).forEach(s -> System.out.println(s));// Lambda表达式简写list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.println(s));} }
1.4Stream流终结操作方法【应用】
-
概念
终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作 -
常见方法
方法名 说明 void forEach(Consumer action) 对此流的每个元素执行操作 long count() 返回此流中的元素数 -
代码演示
public class MyStream5 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("张三丰");list.add("张无忌");list.add("张翠山");list.add("王二麻子");list.add("张良");list.add("谢广坤");method1(list);// long count():返回此流中的元素数long count = list.stream().count();System.out.println(count);}private static void method1(ArrayList<String> list) {// void forEach(Consumer action):对此流的每个元素执行操作// Consumer接口中的方法void accept(T t):对给定的参数执行此操作//s就依次表示了流中的每一个数据.//所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.list.stream().forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});System.out.println("====================");//lambda表达式的简化格式list.stream().forEach(s->System.out.println(s));} }
1.5Stream流的收集操作【应用】
-
概念
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中 -
常用方法
方法名 说明 R collect(Collector collector) 把结果收集到集合中 -
工具类Collectors提供了具体的收集方式
方法名 说明 public static Collector toList() 把元素收集到List集合中 public static Collector toSet() 把元素收集到Set集合中 public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中 -
代码演示
// toList和toSet方法演示 public class MyStream7 {public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();for (int i = 1; i <= 10; i++) {list1.add(i);}list1.add(10);list1.add(10);list1.add(10);list1.add(10);list1.add(10);//filter负责过滤数据的.//collect负责收集数据.//Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.List<Integer> list = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());System.out.println(list);Set<Integer> set = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());System.out.println(set); } } /** Stream流的收集方法 toMap方法演示 创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄 "zhangsan,23" "lisi,24" "wangwu,25" 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值 */ public class MyStream8 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("zhangsan,23");list.add("lisi,24");list.add("wangwu,25");Map<String, Integer> map = list.stream().filter(s -> {String[] split = s.split(",");int age = Integer.parseInt(split[1]);return age >= 24;}//collect方法只能获取到流中剩余的每一个数据.//Collectors.toMap 创建一个map集合并将数据添加到集合当中//s 依次表示流中的每一个数据//第一个lambda表达式就是如何获取到Map中的键//第二个lambda表达式就是如何获取Map中的值).collect(Collectors.toMap(s -> s.split(",")[0],s -> Integer.parseInt(s.split(",")[1]) ));System.out.println(map);} }
1.6Stream流综合练习【应用】
-
案例需求
现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
- 男演员只要名字为3个字的前三人
- 女演员只要姓林的,并且不要第一个
- 把过滤后的男演员姓名和女演员姓名合并到一起
- 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
-
代码实现
演员类
public class Actor {private String name;public Actor(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;} }测试类
public class StreamTest{public static void main(String[] args) {//创建集合ArrayList<String> manList = new ArrayList<String>();Collections.addAll(manList,"周润发","成龙","刘德华","吴京","周星驰","李连杰");ArrayList<String> womanList = new ArrayList<String>();Collections.addAll(womanList,"林心如","张曼玉","林青霞","柳岩","林志玲","王祖贤");//男演员只要名字为3个字的前三人Stream<String> manStream = manList.stream().filter(name -> name.length() == 3).limit(3);//女演员只要姓林的,并且不要第一个Stream<String> womanStream = womanList.stream().filter(name -> name.startsWith("林")).skip(1);//把过滤后的男演员姓名和女演员姓名合并到一起Stream<String> stream = Stream.concat(manStream, womanStream);// 将流中的数据封装成Actor对象之后打印stream.forEach(name -> {Actor actor = new Actor(name);System.out.println(actor);});}}
2.方法引用
2.1体验方法引用【理解】
-
方法引用的出现原因
在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作.那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?
答案肯定是没有必要.那我们又是如何使用已经存在的方案的呢?这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案 -
代码演示
public interface Printable {void printString(String s); }public class PrintableDemo {public static void main(String[] args) {//在主方法中调用usePrintable方法usePrintable((String s) -> {System.out.println(s);});//Lambda简化写法usePrintable(s -> System.out.println(s));//方法引用usePrintable(System.out::println);}private static void usePrintable(Printable p) {p.printString("爱生活爱Java");} }
2.2方法引用符【理解】
-
方法引用符
::该符号为引用运算符,而它所在的表达式被称为方法引用
2.3引用类方法【应用】
引用类方法,其实就是引用类的静态方法
-
格式
类名::静态方法 -
范例
Integer::parseIntInteger类的方法:public static int parseInt(String s) 将此String转换为int类型数据
-
练习描述
- 定义一个接口(Converter),里面定义一个抽象方法 int convert(String s);
- 定义一个测试类(ConverterDemo),在测试类中提供两个方法
- 一个方法是:useConverter(Converter c)
- 一个方法是主方法,在主方法中调用useConverter方法
-
代码演示
public interface Converter {int convert(String s); }public class ConverterDemo {public static void main(String[] args) {//Lambda写法useConverter(s -> Integer.parseInt(s));//引用类方法useConverter(Integer::parseInt);}private static void useConverter(Converter c) {int number = c.convert("666");System.out.println(number);} } -
使用说明
Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数
2.4引用对象的实例方法【应用】
引用对象的实例方法,其实就引用类中的成员方法
-
格式
对象::成员方法 -
范例
HelloWorld::toUpperCaseString类中的方法:public String toUpperCase() 将此String所有字符转换为大写
-
练习描述
-
定义一个类(PrintString),里面定义一个方法
public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出
-
定义一个接口(Printer),里面定义一个抽象方法
void printUpperCase(String s)
-
定义一个测试类(PrinterDemo),在测试类中提供两个方法
- 一个方法是:usePrinter(Printer p)
- 一个方法是主方法,在主方法中调用usePrinter方法
-
-
代码演示
public class PrintString {//把字符串参数变成大写的数据,然后在控制台输出public void printUpper(String s) {String result = s.toUpperCase();System.out.println(result);} }public interface Printer {void printUpperCase(String s); }public class PrinterDemo {public static void main(String[] args) {//Lambda简化写法usePrinter(s -> System.out.println(s.toUpperCase()));//引用对象的实例方法PrintString ps = new PrintString();usePrinter(ps::printUpper);}private static void usePrinter(Printer p) {p.printUpperCase("HelloWorld");} } -
使用说明
Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数
2.5引用类的实例方法【应用】
引用类的实例方法,其实就是引用类中的成员方法
-
格式
类名::成员方法 -
范例
String::substringpublic String substring(int beginIndex,int endIndex)
从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex
-
练习描述
-
定义一个接口(MyString),里面定义一个抽象方法:
String mySubString(String s,int x,int y);
-
定义一个测试类(MyStringDemo),在测试类中提供两个方法
- 一个方法是:useMyString(MyString my)
- 一个方法是主方法,在主方法中调用useMyString方法
-
-
代码演示
public interface MyString {String mySubString(String s,int x,int y); }public class MyStringDemo {public static void main(String[] args) {//Lambda简化写法useMyString((s,x,y) -> s.substring(x,y));//引用类的实例方法useMyString(String::substring);}private static void useMyString(MyString my) {String s = my.mySubString("HelloWorld", 2, 5);System.out.println(s);} } -
使用说明
Lambda表达式被类的实例方法替代的时候
第一个参数作为调用者
后面的参数全部传递给该方法作为参数
2.6引用构造器【应用】
引用构造器,其实就是引用构造方法
-
l格式
类名::new -
范例
Student::new -
练习描述
-
定义一个类(Student),里面有两个成员变量(name,age)
并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法
-
定义一个接口(StudentBuilder),里面定义一个抽象方法
Student build(String name,int age);
-
定义一个测试类(StudentDemo),在测试类中提供两个方法
- 一个方法是:useStudentBuilder(StudentBuilder s)
- 一个方法是主方法,在主方法中调用useStudentBuilder方法
-
-
代码演示
public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }public interface StudentBuilder {Student build(String name,int age); }public class StudentDemo {public static void main(String[] args) {//Lambda简化写法useStudentBuilder((name,age) -> new Student(name,age));//引用构造器useStudentBuilder(Student::new);}private static void useStudentBuilder(StudentBuilder sb) {Student s = sb.build("林青霞", 30);System.out.println(s.getName() + "," + s.getAge());} } -
使用说明
Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
相关文章:
stream流和方法引用
1.Stream流 1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集…...
Redis——某马点评day01——短信登录
项目介绍 导入黑马点评项目 项目架构 基于Session实现登录 基本流程 实现发送短信验证码功能 controller层中 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {// 发送短信…...
AES加密技术:原理与应用
一、引言 随着信息技术的飞速发展,数据安全已成为越来越受到重视的领域。加密技术作为保障数据安全的重要手段,在信息安全领域发挥着举足轻重的作用。AES(Advanced Encryption Standard)作为一种对称加密算法,自1990年…...
Unity中PlayerPrefs在PC上存储位置总结
编辑器下和EXE存储位置是不同的,这也不难理解,是为了避免存储位置相同导致开发和测试冲突。 编辑器下位置:HKEY_CURRENT_USER\Software\Unity\UnityEditor\ExampleCompanyName\ExampleProductName EXE位置:HKEY_CURRENT_USER\Sof…...
消融实验:深度学习的关键分析工具
消融实验:深度学习的关键分析工具 在深度学习和机器学习领域,消融实验(Ablation Study)是一种重要的实验方法,用于理解和评估模型的各个组成部分对其整体性能的贡献。通过这种方法,研究人员可以更深入地了…...
Redis缓存——Spring Cache入门学习
Spring Cache 介绍 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如: EHCacheCaffeineR…...
Python标准库copy【侯小啾python领航班系列(十五)】
Python标准库copy【侯小啾python领航班系列(十五)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…...
Android--Jetpack--Lifecycle详解
富贵本无根,尽从勤里得 一,定义 Lifecycle 是一个具备宿主生命周期感知能力的组件。它持有组件(Activity/Fragment)生命周期状态信息,并且允许其观察者监听宿主生命周期状态变化。 顾名思义,Lifecycle的主…...
LeetCode105.从前序和中序遍历序列构造二叉树
这道题看完题想了几分钟就想到大概的思路了,但是在写的时候有很多细节没注意出了很多问题,然后写了1个多小时,其实这道题挺简单的。 首先,最基本的知识,先序遍历是根左右,中序遍历是左根右,那么…...
flutter-一个可以输入的数字增减器
效果 参考文章 代码 在参考文章上边,主要是改了一下样式,逻辑也比较清楚,对左右两边添加增减方法。 我在此基础上加了_numcontroller 输入框的监听。 加了数字输入框的控制 keyboardType: TextInputType.number, //设置键盘为数字 inputF…...
抑郁症中西医治疗对比?
抑郁症是一种常见的心理障碍,治疗方法包括中医和西医两种。下面就抑郁症中西医治疗进行对比: 治疗方法:中医治疗抑郁症强调整体观念和辨证论治,通过调理身体各部分的功能,达到治疗抑郁症的目的。中医治疗抑郁症多采用天…...
012 OpenCV sobel边缘检测
目录 一、环境 二、soble原理介绍 三、源码实验 一、环境 本文使用环境为: Windows10Python 3.9.17opencv-python 4.8.0.74 二、soble原理介绍 Sobel边缘检测是一种广泛应用于图像处理领域的边缘检测算法,它通过计算图像灰度函数在水平方向和垂直…...
【开源视频联动物联网平台】libmodbus 写一个modbus tcp客户端
libmodbus 是一个用于 Modbus 通信协议的 C 语言库,可以用来创建 Modbus TCP 客户端。以下是一个简单的示例代码,演示如何使用 libmodbus 创建一个 Modbus TCP 客户端。 首先,确保你已经安装了 libmodbus 库。你可以从 libmodbus 的官方网站…...
安装以及使用 stylepro_artistic 所遇问题解决
根据https://github.com/PaddlePaddle/PaddleHub/blob/develop/docs/docs_ch/get_start/windows_quickstart.md 安装 hub install stylepro_artistic1.0.1 出现ImportError: cannot import name ‘Constant’ from ‘paddle.fluid.initializer’,提示在File: "…...
【Rust】所有权的认识
所有权 所有权的认识移动,克隆,拷贝所有权与函数返回值与作用域 引用与借用可变引用悬垂引用(Dangling References) Slice类型 所有权的认识 所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制&#…...
中间件安全:Weblogic 漏洞.(使用工具可以利用多种类型漏洞)
中间件安全:Weblogic 漏洞.(使用工具可以利用多种类型漏洞) WebLogic 是美国 Oracle 公司出品的一个 application server,确切的说是一个基于 JAVA EE 架构的中间件,WebLogic 是用于开发、集成、部署和管理大型分布式…...
matlab操作方法(一)——向量及其操作
1.向量及其操作 matlab是英文Matrix Laboratory(矩阵实验室)的简称,是基于矩阵运算的操作环境。matlab中的所有数据都是以矩阵或多维数组的形式存储的。向量和标量是矩阵的两种特殊形式 向量是指单行或者单列的矩阵,它是构成矩阵…...
MicroPython标准库
MicroPython标准库 arraybinascii(二进制/ASCII转换)builtins – 内置函数和异常cmath – 复数的数学函数collections – 集合和容器类型errno – 系统错误代码gc – 控制垃圾收集器hashlib – 散列算法heapq – 堆队列算法io – 输入/输出流json – JSON 编码和解码math – 数…...
2023年产业数据价值化峰会暨数栖大会-核心PPT资料下载
一、峰会简介 本次大会由主论坛和3场分论坛组成,嘉宾阵容强大,内容丰富多彩。来自政企学界的百名专家从产学研用多种维度对企业数据管理、产业数据资源化建设等视角展开。大会围绕“产业数据价值化”为主题,秉持“让数据用起来”的使命&…...
深入理解 Vue 组件:构建优雅的前端应用
🍂引言: Vue.js 是一款流行的 JavaScript 框架,以其简单易用和高度灵活的特性而受到了广泛的欢迎。其中的一个重要概念就是组件,它使我们能够将用户界面划分为可重用的、独立的部分。本文将深入探讨 Vue 组件的概念、使用和最佳实…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
