Java8特性-Lambda表达式
📕概述
在Java 8中引入了Lambda表达式作为一项重要的语言特性,可以堪称是一种语法糖。Lambda表达式使得以函数式编程的方式解决问题变得更加简洁和便捷。
Lambda表达式的语法如下:
(parameters) -> expression
(参数) -> {代码}
其中,parameters是Lambda表达式的参数列表,可以是零个或多个参数,如果有多个参数,用逗号分隔;expression是Lambda表达式的函数体,可以是一个表达式或一段语句块。
❗使用Lambda表达式的条件
-
函数式接口:Lambda表达式只能用于函数式接口(Functional Interface)的实现。函数式接口是指只包含一个抽象方法的接口。函数式接口可以使用@FunctionalInterface注解显式声明,但这并非必要,只要满足函数式接口的特征即可。
-
上下文匹配:Lambda表达式必须与上下文(Context)相匹配,即Lambda表达式的参数和返回类型必须与目标上下文的参数和返回类型相匹配。例如,Lambda表达式可以作为方法的参数或赋值给一个接口类型的变量。
📕Lambda表达式
以下是一个简单的Lambda表达式的示例:
//Lambda表达式作为匿名函数实现两个数相加
MathOperation addition = (int a,int b) -> a+b;
int result = addition.operation(2,3);//结果为5
在这个示例中,我们定义了一个MathOperation接口,并使用Lambda表达式作为接口的实现。Lambda表达式接受两个整数参数a和b,并返回它们的和。
🏷例1
public class LambdaTest {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("线程开始"); }}).start();}
}
使用Lambda表达式实现就是这样子的:
public class LambdaTest {public static void main(String[] args) {new Thread(() -> System.out.println("线程开始")).start();}
}
🏷例2
public class LambdaTest {public static void main(String[] args) {int b = calculateNum(new IntBinaryOperator() {@Overridepublic int applyAsInt(int left, int right) {return left + right;}});System.out.println(b);}public static int calculateNum(IntBinaryOperator operator){int a = 10;int b = 20;return operator.applyAsInt(a,b);}
}
使用Lambda表达式就是这个样子的:
public class LambdaTest {public static void main(String[] args) {int b = calculateNum((left, right) -> left + right);System.out.println(b);}public static int calculateNum(IntBinaryOperator operator){int a = 10;int b = 20;return operator.applyAsInt(a,b);}
}

还差那么点意思是吧🤭,因为啥,因为return是吧,为啥掉了呢,其实没有掉,你把left+right改成{return left+right}试试,那肯定是不会报错的,left+right是表达式,加个return就是语句了,所以需要加上{}包裹着。你再看,和左边去掉之后有没有哪里不一样。
这里说明:注意使用Lambda表达式的前提吼,Lambda表达它不需要知道你接口名,也不需要知道你的接口内的方法名,但是哦,可得记住,这个接口内只能有一个抽象方法,那么我们就可以直接把不需要的东西去掉,简化后的代码就是Lambda表达式,但是这个时候你如果安装了idea的一些插件,他可能会提示你说还可以转换成Lambda更简化的表达式,不要着急,咱们慢慢来来!

🏷例3
public class LambdaTest {public static void main(String[] args) {printNum(new IntPredicate() {@Overridepublic boolean test(int value) {return value%2==0;}});}public static void printNum(IntPredicate intPredicate){int[] arr = {1,2,3,4,5,6,7,8,9};for (int i : arr) {if(intPredicate.test(i)){System.out.println(i);}}}
}
改为Lambda表达式:
public class LambdaTest2 {public static void main(String[] args) {printNum((int value) ->{return value%2==0;});}public static void printNum(IntPredicate intPredicate){int[] arr = {1,2,3,4,5,6,7,8,9};for (int i : arr) {if(intPredicate.test(i)){System.out.println(i);}}}
}

就这么简单,不用怀疑,就是这么简单,但是这还不是最简化的形式。
🏷例4

🆗,例子到此结束,这四个例子可以看出,转换Lambda表达式,接口名和方法名我们no care,我们只关注这个参数。咱们继续 👇
📕转换Lambda表达式简化规则
- 参数类型可以省略
- 方法体只有一句代码时,大括号return和唯一一句代码的分号可以省略
- 方法只有一个参数时小括号可以省略
- 以上这些规则都记不住也可以省略不记(因为IDEA有快捷键可以实现)Alt+Enter
我们看上面说到的最后一个例子:简化的前提是,先转换成Lambda表达式再简化

这其实就和右边的一样了 。
当然还有更简化的方式啊,就是简化Integer.valueOf(str)为Integer::valueOf,这个是为什么呢?
在Java中,Integer.valueof是调用静态方法的一种方式。它表示调用Integer类的valueof方法,将一个基本类型的整数值转换为对应的Integer对象。
而Integer::valueof则是Java 8引入的方法引用(Method Reference)的语法。它也表示调用Integer类的valueof方法,并且可以作为Lambda表达式的替代形式使用。相当于把方法引用包装成一个函数接口。
因此,Integer.valueof和Integer::valueof的作用是完全相同的,只是语法上的不同而已。它们都用于将基本类型的整数值转换为对应的Integer对象。
那么类似这样的,都可以转换:
byte by = 10;
Byte byteObj = Byte.valueOf(by); // 将byte类型的值转换为Byte对象short sh = 100;
Short shortObj = Short.valueOf(sh); // 将short类型的值转换为Short对象int i = 1000;
Integer intObj = Integer.valueOf(i); // 将int类型的值转换为Integer对象long l = 1000000L;
Long longObj = Long.valueOf(l); // 将long类型的值转换为Long对象float f = 3.14f;
Float floatObj = Float.valueOf(f); // 将float类型的值转换为Float对象double d = 1.4142135;
Double doubleObj = Double.valueOf(d); // 将double类型的值转换为Double对象
如果这种不会转换,那就用快捷键吧。
📕Stream流
🏷准备工作
/*** @author 小白程序员* @Classname Author* @Description TODO干啥呢* @date 2023/9/3 17:39*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode //后期去重的使用
public class Author {private Long id;private String name;private Integer age;private String intro;private List<Book> books;
}/*** @author 小白程序员* @Classname Book* @Description TODO干啥呢* @date 2023/9/3 17:41*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Book {private Long id;private String name;private String category;private Integer score;private String intro;
}/*** @author 小白程序员* @Classname BookService* @Description TODO干啥呢* @date 2023/9/3 17:43*/
public class BookService {public static void main(String[] args) {//后面的代码都写在这一块的来测试}private static List<Author> getAuthors() {Author author = new Author(1L, "蒙多", 17, "一个祖安人", null);Author author2 = new Author(2L, "亚拉索", 18, "艾欧尼亚", null);Author author3 = new Author(3L, "易大师", 19, "黑色玫瑰", null);Author author4 = new Author(3L, "易大师", 19, "黑色玫瑰", null);List<Book> book1 = new ArrayList<>();List<Book> book2 = new ArrayList<>();List<Book> book3 = new ArrayList<>();List<Book> book4 = new ArrayList<>();book1.add(new Book(1L,"*","哲学,爱情", 80, "*"));book1.add(new Book(2L,"**","爱情,个人成长", 80, "**"));book2.add(new Book(3L,"***","爱情,传记", 70, "***"));book2.add(new Book(3L,"****","个人成长,传记", 70, "****"));book2.add(new Book(4L,"*****","哲学", 70, "*****"));book3.add(new Book(5L,"******","个人成长", 60, "******"));book3.add(new Book(6L,"*******","传记", 60, "*******"));book3.add(new Book(6L,"********","爱情", 60, "********"));book4.add(new Book(5L,"******","个人成长", 60, "******"));book4.add(new Book(6L,"*******","个人成长,传记,爱情", 60, "*******"));book4.add(new Book(6L,"********","哲学,爱情,个人成长", 60, "********"));author.setBooks(book1);author2.setBooks(book2);author3.setBooks(book3);author4.setBooks(book4);List<Author> authors = new ArrayList<>(Arrays.asList(author,author2,author3,author4));return authors;}
}
🏷案例分析
案例:获取年龄小于18的作家
public static void main(String[] args) {//查询出年龄小于18的作家的名字List<Author> authors = getAuthors();authors.stream().distinct().filter(new Predicate<Author>() {@Overridepublic boolean test(Author author) {return author.getAge() < 18;}}).forEach(new Consumer<Author>() {@Overridepublic void accept(Author author) {System.out.println(author.getName());}});
}//Lambda表达式优化
public static void main(String[] args) {//查询出年龄小于18的作家的名字List<Author> authors = getAuthors();authors.stream().distinct().filter(author -> author.getAge() < 18).forEach(author -> System.out.println(author.getName()));}
解释说明一下:authors.stream()是把集合转换成流形式,.distinct()是去重,.filter()是过滤,.forEach()是循环输出。


🏷常用操作
🔖创建流
①单例集合:集合对象.stream()
List<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.stream();
②数组:Arrays.stream(数组)或Stream.of(数组)来创建
Integer[] arr = {1,2,3,4};
Stream<Integer> stream1 = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);
③双例集合:转换成单例集合再创建
Map<String, String> map = new HashMap<>();
Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();
🔖中间操作
①filter
对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。
public static void main(String[] args) {//查询出年龄小于18的作家的名字List<Author> authors = getAuthors();authors.stream().distinct().filter(author -> author.getAge() < 18)//中间操作.forEach(author -> System.out.println(author.getName()));//终结操作}
②map
可以把流中的元素进行计算或转换。
public static void main(String[] args) {List<Author> authors = getAuthors();authors.stream().map(new Function<Author, String>() {//泛型中,第一个参数为方法的参数类型(流中的类型),第二个参数为方法的返回值类型@Overridepublic String apply(Author author) {return author.getName();}}).forEach(new Consumer<String>() {@Overridepublic void accept(String name) {System.out.println(name);}});
}//Lambda表达式优化public static void main(String[] args) {List<Author> authors = getAuthors();//泛型中,第一个参数为方法的参数类型(流中的类型),第二个参数为方法的返回值类型authors.stream().map(author -> author.getName()).forEach(name -> System.out.println(name));}
由此可以看出,Lambda表达式是有多么简化代码。
计算使用
public static void test() {List<Author> authors = getAuthors();//泛型中,第一个参数为方法的参数类型,第二个参数为方法的返回值类型authors.stream().map(author -> author.getAge()).map(age -> age+10).forEach(age -> System.out.println(age));
}
③distinct
去除流中重复的元素。
❗distinct方法是依赖Object类中的equals方法来判断是否是相同对象,所以需要重写equals方法
④sorted
对流中的元素进行排序
👍调用sorted()空参方法
在比较的实体类上要实现Comparable接口,不然会报类型不匹配的异常。
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode //后期去重的使用
public class Author implements Comparable<Author>{private Long id;private String name;private Integer age;private String intro;private List<Book> books;@Overridepublic int compareTo(Author o) {return this.getAge()-o.getAge();}
}
public static void test2(){List<Author> authors = getAuthors();authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getName()));}
这里sorted内没有参数是因为在实体类中定义了比较的方式,所以不用传递参数。
👍在sorted方法中实现Comparator接口
首先把Author中实现的东西去掉,用Lambda表达式方式写比较条件。sorted()方法中的new Comparator<T>是一个函数式接口,内部只有一个和compare抽象方法。
public static void test3() {List<Author> authors = getAuthors();authors.stream().distinct().sorted(new Comparator<Author>() {@Overridepublic int compare(Author o1, Author o2) {return o1.getAge()-o2.getAge();}}).forEach(author -> System.out.println(author.getAge()));
}
优化
public static void test3(){List<Author> authors = getAuthors();authors.stream().distinct().sorted(((o1, o2) -> o2.getAge()- o1.getAge())).forEach(author -> System.out.println(author.getAge()));}
⑤limit
可以设置流的最大长度,超出的部分将被抛弃。
public static void test4(){List<Author> authors = getAuthors();authors.stream().distinct().sorted(((o1, o2) -> o2.getAge()- o1.getAge())).limit(2).forEach(System.out::println);}
⑥skip
跳过流中的前N个元素,返回剩下的元素。
⑦flatMap
map方式:map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。
案例:打印所有书籍,要求对重复的元素进行去重。
map方式:Author对象的books属性是集合类型,使用原来map转换对象,要使用嵌套循环进行打印。
public static void test5() {List<Author> authors = getAuthors();authors.stream().map(Author::getBooks).forEach(books -> {books.forEach(System.out::println);});}
flatMap方式:
public static void test6() {List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).forEach(System.out::println);}
案例二:打印现有数据的所有分类,要求对分类进行去重。不能出现这种格式:哲学,爱情,要将它们拆开输出。
public static void test7(){List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).distinct().flatMap(book -> Arrays.stream(book.getCategory().split(","))).distinct().forEach(System.out::println);}
🔖终结操作
①forEach
对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体的操作。
②count
获取当前流中的元素个数。
public static void test8(){List<Author> authors = getAuthors();Long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();System.out.println(count);}
③max&min
获取流中的最值
public static void test9(){List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getScore).max(((o1, o2) -> o2-o1));Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(Book::getScore).max(((o1, o2) -> o1-o2));System.out.println(max);System.out.println(min);}
④collect
把当前流的元素转换成一个集合
//获取一个存放所有作者名字的list集合
public static void test5() {List<Author> authors = getAuthors();List<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toList());System.out.println(nameList);
}
list集合、set集合、map集合都是类似的
注意map的是两个参数哦:collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()))
⑤查找与匹配
(1)anyMatch:判断是否有任意符合匹配条件的元素,结果为Boolean类型。
public static void test9(){List<Author> authors = getAuthors();boolean flag = authors.stream().anyMatch(author -> author.getAge()>18);System.out.println(flag);}
(2)allMatch:判断是否都符合条件,如果都符合返回true,否则返回false
public static void test10(){List<Author> authors = getAuthors();boolean b = authors.stream().allMatch(author -> author.getAge() > 18);System.out.println(b);}
(3)noneMatch:判断流中的元素是否都不符合匹配条件,如果都不符合结果为true,否则为false
(4)findAny:获取流中的任意一个元素,该方法没有办法保证获取到的一定是流中的第一个元素。
public static void test11(){//获取任意一个年龄大于18的作家List<Author> authors = getAuthors();Optional<Author> any = authors.stream().filter(author -> author.getAge() > 50).findAny();//如果这个Optional中有元素,则执行方法,没有就不执行any.ifPresent(System.out::println);}
(5)findFirst:获取流中的第一个元素
public static void test12(){//获取一个年龄最小的作家List<Author> authors = getAuthors();Optional<Author> firstOne = authors.stream().sorted((o1, o2) -> o1.getAge() - o2.getAge()).findFirst();firstOne.ifPresent(System.out::println);}
(6)reduce归并:对流中的数据按照指定的计算方式计算出一个结果
reduce的作用是把Stream中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式一次拿流中的元素和初始值进行计算,计算结果再和后面的元素计算。
它内部的计算方式如下:
T result = identity;
for (T element : this stream)result = accumulator.apply(result, element)
return result;
其中identity就是我们可以通过方法参数传入的初始值,accumulator的apply具体进行什么计算也是我们通过方法参数来确定的。
案例1:使用reduce求所有作者年龄的和
public static void test13(){List<Author> authors = getAuthors();Integer sum = authors.stream().distinct().map(Author::getAge).reduce(0,(result,element) -> result + element);System.out.println(sum);}
案例2:使用reduce求所有作者中年龄的最大值
public static void test14(){List<Author> authors = getAuthors();Integer max = authors.stream().map(Author::getAge).reduce(Integer.MIN_VALUE,(result,element) -> result > element ? result : element);System.out.println(max);}
reduce有个重载形式,内部代码如下:
boolean foundAny = false;
T result = null;
for (T element : this stream) {if(!foundAny) {foundAny = true;result = element;} else {result = accumulator.apply(result, element);}
}
return foundAny ? Optional.of(result) : Optional.empty();
利用这个重载形式,求作者年龄的最大值,不用传递初始值了。
public static void test8() {List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().map(author -> author.getAge()).reduce((result, element) -> result > element ? result : element);System.out.println(max.get());
}
❗惰性求值:如果没有终结操作,中间操作是不会得到执行的。
❗流是一次性的:一旦一个流对象经过一个终结操作后,这个流就不能在被使用了,只能重新创建流对象再使用。
❗不会影响原数据:我们在流中可以对数据做很多处理,但正常情况下是不会影响原来集合中的元素的。
相关文章:
Java8特性-Lambda表达式
📕概述 在Java 8中引入了Lambda表达式作为一项重要的语言特性,可以堪称是一种语法糖。Lambda表达式使得以函数式编程的方式解决问题变得更加简洁和便捷。 Lambda表达式的语法如下: (parameters) -> expression (参数) -> {代码}其中&…...
通过Power Platform自定义D365CE业务需求 - 1. Microsoft Power Apps 简介
Microsoft Power Apps是一个趋势性的、无代码和无代码的商业应用程序开发平台,配有一套应用程序、服务和连接器。其数据平台为构建适合任何业务需求的自定义业务应用程序提供了快速开发环境。随着无代码、少代码应用程序开发的引入,任何人都可以快速构建低代码应用程序,并与…...
简易实现QT中的virtualkeyboard及问题总结
文章目录 前言:一、虚拟键盘的实现综合代码 二、为什么选用QWidget而不适用QDialog实现键盘三、从窗体a拉起窗体b后,窗体b闪退问题的探讨四、关闭主窗口时子窗口未关闭的问题 前言: 本文章主要包含四部分: 虚拟键盘的实现&#…...
景联文科技可为多模态语音翻译模型提供数据采集支持
8月22日Facebook的母公司Meta Platforms发布了一种能够翻译和转录数十种语言的人工智能模型——SeamlessM4T,可以在日常生活中或者商务交流中为用户提供更便捷的翻译和转录服务。 相较于传统的文本翻译,这项技术的最大区别在于它可以实现端到端的语音翻译…...
定时器分批请求数据
<!DOCTYPE html> <html><script>//需要分页的数组let arr [1,2,3,4,5,6,7,8,9,10]//分割数组,每页3条splitArr(arr,4)/*** 分割数组*/function splitArr(idList,size){//当前页数let num 1//共多少页let count Math.ceil(idList.length / siz…...
【华为OD机试python】报数游戏【2023 B卷|100分】
【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 100个人围成一圈,每个人有一个编码,编号从1开始到100。 他们从1开始依次报数,报到为M的人自动退出圈圈,然后下一个人接着从1开始报数, 直到剩余的人数小于M。 请问最后剩余的人在原先…...
【深度学习实战—6】:基于Pytorch的血细胞图像分类(通用型图像分类程序)
✨博客主页:米开朗琪罗~🎈 ✨博主爱好:羽毛球🏸 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深…...
华清远见第六课程day4作业
仿照string类,完成myString 类 #include <iostream> #include <cstring>using namespace std;class myString{ private:char *str;int size; public:myString():size(10){str new char[size];strcpy(str,"");}myString(const char*s){size …...
【广州华锐互动】AR远程智慧巡检在化工行业中的应用
AR远程智慧巡检是一种基于增强现实技术的新型巡检方式,它可以利用虚拟信息和现实场景的结合,实现对设备、工艺流程等方面的实时监测和识别。在化工行业中,AR远程智慧巡检具有广泛的应用前景,可以提高生产效率和安全性。 一、设备巡…...
easyui-sidemenu 菜单 后台加载
前言 一个项目的功能较齐全,而齐全就预示着功能菜单比较长,但是现实中在不同的甲方使用中往往只需要摘取其中几项功能,所以就想到用配置菜单以满足其需求,且无需变更原始代码,查找一些资料总是似是而非或是誊抄别的什…...
Python总结上传图片到服务器并保存的两种方式
一、前言 图片保存到服务器的两种方法: 1、根据图片的 URL 将其保存到服务器的固定位置 2、根据 request.FILES.get("file") 方式从请求中获取上传的图片文件,并将其保存到服务器的固定位置 二、方法 1、图片的 URL 要根据图片的 URL 将…...
【ETH】以太坊合约智能合约逆向方案
技术角度了解区块链 区块链技术逆袭专栏 文章目录 区块链技术逆袭专栏获取合约代码逆向工具方案1方案2实操演示:获取合约代码 在反编译之前,你需要先知道如果获取编译后的字节码。 这里以 USDT 举例 eth.getCode(0xdAC17F958D2ee523a2206206994597C13D831ec7)字节码: 0x…...
C高级Day5
课后作业: rootlinux:~/shell# cat qh.sh #!/bin/bash function sum_array() {local brr($*) local sum0for i in ${brr[*]} dosum$((sum i))doneecho $sum } arr(1 2 3 4 5) result$(sum_array ${arr[*]}) echo "数组的和为: $result"#!/bin/bash fun…...
AI绘画:Midjourney超详细教程Al表情包超简单制作,内附关键词和变现方式
大家好,本篇文章主要介绍AI绘画完成表情包的制作和变现方式分享。 你还不会AI表情包制作吗?下面我们详细的拆解制作过程。跟着这个教程做出一套属于自己的表情包。 核心工具Midjourney PS,你就可以得到一套自己的专属表情包啦~ 整体制作…...
Linux dup dup2函数
/*#include <unistd.h>int dup2(int oldfd, int newfd);作用:重定向文件描述符oldfd 指向 a.txt, newfd 指向b.txt,调用函数之后,newfd和b.txt close,newfd指向a.txtoldfd必须是一个有效的文件描述符 */ #include <unistd.h> #i…...
设计模式系列-外观模式
一、上篇回顾 上篇我们主要讲述了创建型模式中的最后一个模式-原型模式,我们主要讲述了原型模式的几类实现方案,和原型模式的应用的场景和特点,原型模式 适合在哪些场景下使用呢?我们先来回顾一下我们上篇讲述的3个常用的场景。 1…...
DBeaver 下载、安装与数据库连接(MySQL)详细教程【超详细,保姆级教程!!!】
本文介绍DBeaver 下载、安装与数据库连接(MySQL)的详细教程 一、DBeaver 下载 官网下载地址:https://dbeaver.io/download/ 二、安装 1、双击下载的安装包,选择中文 2、点击下一步 3、点击我接受 4、如下勾选,…...
使用adjustText解决标签文字遮挡问题python
使用adjustText解决文字遮挡问题 1、一个例子2、adjust_text的用法使用pip install adjustText或conda install -c conda-forge adjusttext来安装adjustText。安装成功之后,首先生成随机示例数据以方便之后的演示: 1、一个例子 我们先不使用adjustText调整图像,直接绘制出原…...
[论文笔记]SiameseNet
引言 这是Learning Text Similarity with Siamese Recurrent Networks的论文笔记。 论文标题意思是利用孪生循环神经网络学习文本相似性。 什么是孪生神经网络呢?满足以下两个条件即可: 输入是成对的网络结构和参数共享(即同一个网络)如下图所示: 看到这种图要知道可能代…...
只有个体户执照,可以用来在抖音开店吗?抖店开通问题解答
我是王路飞。 在抖音开店的门槛,本身就是需要有营业执照的。 至于执照的类型,其实主要看商家自己。 如果你是新手商家,之前也没有怎么接触过电商行业,那么用个体执照在抖音开店足够用了,毕竟你要先入门,…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
CTF show 数学不及格
拿到题目先查一下壳,看一下信息 发现是一个ELF文件,64位的 用IDA Pro 64 打开这个文件 然后点击F5进行伪代码转换 可以看到有五个if判断,第一个argc ! 5这个判断并没有起太大作用,主要是下面四个if判断 根据题目…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...

