JDK8特性学习笔记

文章目录

  • 1Lambda表达式
    • 1.1标准格式
    • 1.2底层原理
    • 1.3省略格式
    • 1.4前提条件
    • 1.5和匿名内部类对比
    • 1.6接口默认方法
    • 1.7接口静态方法
    • 1.8常用内置函数式接口
      • 1.8.1Supplier
      • 1.8.2Consumer
      • 1.8.3Function
      • 1.8.4Predicate
    • 1.9方法引用
      • 1.9.1对象名::引用成员方法
      • 1.9.2类名::静态方法
      • 1.9.3类名::引用实例方法
      • 1.9.4类名::new引用构造方法
      • 1.9.5数组::new引用数组构造方法
  • 2Stream流操作
    • 2.1获取Stream
    • 2.2注意事项
    • 2.3常用方法
      • 2.3.1forEach遍历
      • 2.3.2count统计
      • 2.3.3filter过滤
      • 2.3.4limit截取
      • 2.3.5skip跳过
      • 2.3.6map映射
      • 2.3.7sorted排序
      • 2.3.8distinct去重
      • 2.3.9match匹配
      • 2.3.10find查找
      • 2.3.11max,min最大最小
      • 2.3.12reduce归纳
      • 2.3.13mapToInt转为int
      • 2.3.14concat合并
    • 2.4收集结果
      • 2.4.1收集到集合、数组
      • 2.4.2聚合
      • 2.4.3分组
      • 2.4.4分区
      • 2.4.5拼接
    • 2.5并行Stream流
      • 2.5.1获取并行流
      • 2.5.2线程安全
      • 2.5.3Fork/Join框架
    • 2.6Optional
  • 3日期时间API
    • 3.1日期时间类
    • 3.2时间格式化与解析
    • 3.3Instant
    • 3.4日期时间差
    • 3.5时间调整
    • 3.6设置时区
  • 4重复注解与类型注解
    • 4.1重复注解
    • 4.2类型注解

1Lambda表达式

1.1标准格式

(参数列表) -> {}

方法的参数是接口类型可以考虑用Lambda表达式

无参数无返回值

public interface EatAble {public abstract void eat();
}
public class LambdaDemo {public static void main(String[] args) {doEat(() -> {System.out.println("eat food");});}private static void doEat(EatAble e) {e.eat();}
}

有参数有返回值

public interface DriveAble {public abstract String drive(String name);
}
public class LambdaDemo {public static void main(String[] args) {doDrive((String name) -> {System.out.println("drive " + name);return name;});}private static void doDrive(DriveAble d) {String car = d.drive("byd");System.out.println("car=" + car);}}

1.2底层原理

匿名内部类:编译后生成一个新的类

Lambda表达式:编译后生成一个私有静态方法,表达式的代码会放到方法中,实际上也会生成一个匿名内部类重写抽象方法

1.3省略格式

  • 小括号内参数类型可以省略

  • 小括号只有一个参数,括号可以省略

  • 大括号只有一个语句,可以省略大括号、return、分号

1.4前提条件

  • 方法参数或局部变量为接口

  • 接口只有一个抽象方法(函数式接口)

@FunctionalInterface // 检测接口是否只有一个抽象方法
public interface EatAble {public abstract void eat();
}

1.5和匿名内部类对比

  • 匿名内部类需要的类型是类,抽象类,接口;Lambda需要的类型是接口

  • 匿名内部类的抽象方法数量任意;Lambda的抽象方法只有一个

  • 匿名内部类编译后形成class;Lambda运行时动态生成class

1.6接口默认方法

实现类可以不重写默认方法,也可以重写

public interface DriveAble {public abstract String drive(String name);default void print() {System.out.println("print");}
}
public class MyDrive implements DriveAble {@Overridepublic String drive(String name) {return null;}
}

1.7接口静态方法

实现类无法重写、无法调用静态方法

public interface DriveAble {static void create() {System.out.println("create");}
}

1.8常用内置函数式接口

1.8.1Supplier

供给型接口

public class SupplierDemo {public static void main(String[] args) {printMax(() -> {int[] array = {1, 2, 3};Arrays.sort(array);return array[array.length - 1];});}private static void printMax(Supplier<Integer> supplier) {Integer value = supplier.get();System.out.println("value=" + value);}
}

1.8.2Consumer

消费型接口

public class ConsumerDemo {public static void main(String[] args) {print((String s) -> {System.out.println("upper case=" + s.toUpperCase());});}private static void print(Consumer<String> consumer) {consumer.accept("hello");}
}
public class ConsumerDemo2 {public static void main(String[] args) {print((String s) -> {System.out.println("upper case=" + s.toUpperCase());}, (String s) -> {System.out.println("lower case=" + s.toLowerCase());});}private static void print(Consumer<String> c1, Consumer<String> c2) {// 先调用c1后调用c2c1.andThen(c2).accept("Hello");}
}

1.8.3Function

类型转换接口

public class FunctionDemo {public static void main(String[] args) {getNumber((String s) -> {return Integer.parseInt(s);});}private static void getNumber(Function<String, Integer> function) {Integer num = function.apply("10");System.out.println(num);}
}
public class FunctionDemo2 {public static void main(String[] args) {getNumber((String s) -> {return Integer.parseInt(s);}, (Integer i) -> {return i * 5;});}private static void getNumber(Function<String, Integer> f1, Function<Integer, Integer> f2) {Integer num = f1.andThen(f2).apply("10");System.out.println(num);}
}

1.8.4Predicate

判断型接口

public class PredicateDemo {public static void main(String[] args) {isGreaterThanTen((Integer i) -> {return i > 10;});}private static void isGreaterThanTen(Predicate<Integer> predicate) {boolean flag = predicate.test(13);System.out.println(flag);}
}
public class PredicateDemo2 {public static void main(String[] args) {isGreaterThanTen((Integer i) -> {return i > 10;}, (Integer i) -> {return i < 15;});}private static void isGreaterThanTen(Predicate<Integer> p1, Predicate<Integer> p2) {boolean flag = p1.and(p2).test(13);System.out.println(flag);}
}

1.9方法引用

格式:::

常见引用方式

  • 对象::方法名

  • 类名::静态方法

  • 类名::普通方法

  • 类名::new

  • 数组::new

1.9.1对象名::引用成员方法

被引用的方法,参数要和接口中抽象方法的参数一样

接口抽象方法有返回值,被引用的方法必须有返回值

public static void main(String[] args) {Date date = new Date();Supplier<Long> supplier = date::getTime;System.out.println(supplier.get());}

1.9.2类名::静态方法

 public static void main(String[] args) {Supplier<Long> supplier = System::currentTimeMillis;System.out.println(supplier.get());}

1.9.3类名::引用实例方法

将第一个参数作为方法的调用者

public static void main(String[] args) {Function<String, Integer> function = String::length;System.out.println(function.apply("hello"));}
public static void main(String[] args) {BiFunction<String, Integer, String> biFunction = String::substring;System.out.println(biFunction.apply("hello", 1));}

1.9.4类名::new引用构造方法

public class Person {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
public static void main(String[] args) {Supplier<Person> supplier = Person::new;System.out.println(supplier.get());}

1.9.5数组::new引用数组构造方法

public static void main(String[] args) {Function<Integer, int[]> function = int[]::new;int[] array = function.apply(5);System.out.println(Arrays.toString(array));}

2Stream流操作

类似于生产流水线,不是一种数据结构,不保存数据,只是对数据加工

2.1获取Stream

根据Collection获取

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

Stream.of获取

基本类型的数组不可用

String[] strings = new String[]{"123", "456"};
Stream<String> stream1 = Stream.of(strings);

2.2注意事项

Stream只能操作一次

Stream方法返回的是新的流

Stream不调用终结方法,中间操作不会执行

2.3常用方法

2.3.1forEach遍历

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456");
list.stream().forEach(System.out::println);

2.3.2count统计

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456");
System.out.println(list.stream().count());

2.3.3filter过滤

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456", "78");
list.stream().filter(s -> s.length() == 2).forEach(System.out::println)

2.3.4limit截取

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456", "78");
list.stream().limit(2).forEach(System.out::println);

2.3.5skip跳过

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456", "78");
list.stream().skip(2).forEach(System.out::println);

2.3.6map映射

List<String> list = new ArrayList<>();
Collections.addAll(list, "123", "456", "78");
list.stream().map(Integer::parseInt).forEach(System.out::println);

2.3.7sorted排序

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 123, 456, 78);
list.stream().sorted((i1, i2) -> i2 - i1).forEach(System.out::println);

2.3.8distinct去重

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 123, 456, 78, 123);
list.stream().distinct().forEach(System.out::println);

如果Stream是自定义类型,需要重写equals, hashCode方法

2.3.9match匹配

allMatch全部匹配

anyMatch任意匹配

nonMatch全部不匹配

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 123, 456, 78, 123);
System.out.println(list.stream().allMatch(i -> i > 0));

2.3.10find查找

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 123, 456, 78, 123);
Optional<Integer> first = list.stream().findFirst();
System.out.println(first.get());

2.3.11max,min最大最小

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 123, 456, 78, 123);
Optional<Integer> max = list.stream().max((i1, i2) -> i1 - i2);
System.out.println(max.get());

2.3.12reduce归纳

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4);
Integer reduce = list.stream().reduce(0, (a, b) -> a + b);
System.out.println(reduce);

2.3.13mapToInt转为int

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4);
list.stream().mapToInt(Integer::intValue).filter(i -> i > 2).forEach(System.out::println);

2.3.14concat合并

合并后不能操作之前的流

List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2);
List<Integer> list2 = new ArrayList<>();
Collections.addAll(list2, 3, 4);
Stream.concat(list.stream(), list2.stream()).forEach(System.out::println);

2.4收集结果

2.4.1收集到集合、数组

Stream<String> stream = Stream.of("123", "456");
List<String> list = stream.collect(Collectors.toList());
Stream<String> stream = Stream.of("123", "456");
String[] array = stream.toArray(String[]::new);

2.4.2聚合

最大值:maxBy

最小值:minBy

平均:averagingInt

求和:summingInt

统计:counting

Stream<Student> stream = Stream.of(new Student(10), new Student(20));
Optional<Student> max = stream.collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()));
System.out.println(max.get());

2.4.3分组

Stream<Student> stream = Stream.of(new Student(10), new Student(10), new Student(20));
Map<Integer, List<Student>> map = stream.collect(Collectors.groupingBy(Student::getAge));
map.forEach((k, v) -> System.out.println("k=" + k + ",v=" + v));

多级分组

Stream<Student> stream = Stream.of(new Student(10, "male"), new Student(10, "female"), new Student(20, "male"));
Map<Integer, Map<String, List<Student>>> map = stream.collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(Student::getGender)));
map.forEach((k ,v) -> {System.out.println("k=" + k);v.forEach((k2, v2) -> System.out.println("k2=" + k2 + ",v2=" + v2));
});

2.4.4分区

Stream<Student> stream = Stream.of(new Student(10), new Student(10), new Student(20));
Map<Boolean, List<Student>> map = stream.collect(Collectors.partitioningBy(s -> s.getAge() > 15));
map.forEach((k, v) -> System.out.println("k=" + k + ",v=" + v));

2.4.5拼接

Stream<Student> stream = Stream.of(new Student(10, "male"), new Student(10, "female"), new Student(20, "male"));
String string = stream.map(Student::getGender).collect(Collectors.joining(","));
System.out.println(string);

2.5并行Stream流

多线程处理

2.5.1获取并行流

List<Integer> list = new ArrayList<>();
// 直接获取
Stream<Integer> parallelStream = list.parallelStream();
// 串行转并行
Stream<Integer> parallelStream2 = Stream.of(1, 2, 3, 4, 5).parallel();

2.5.2线程安全

加同步代码块

List<Integer> list = new ArrayList<>();
Object obj = new Object();
IntStream.rangeClosed(1, 1000).parallel().forEach(i -> {synchronized (obj) {list.add(i);}
});
System.out.println(list.size());

使用线程安全集合

Vector<Integer> list = new Vector<>();
Object obj = new Object();
IntStream.rangeClosed(1, 1000).parallel().forEach(i -> {list.add(i);
});
System.out.println(list.size());
List<Integer> list2 = new ArrayList<>();
List<Integer> synchronizedList = Collections.synchronizedList(list2);

使用collect/toArray

List<Integer> list = IntStream.rangeClosed(1, 1000).parallel().boxed().collect(Collectors.toList());
System.out.println(list.size());

2.5.3Fork/Join框架

分治,一个大任务拆分成很多小任务异步执行

工作窃取算法

2.6Optional

防止空指针异常

创建Optional对象

Optional<String> o1 = Optional.of("123");
Optional<Object> o2 = Optional.ofNullable(null);
Optional<Object> o3 = Optional.empty();

获取值

Optional<String> o1 = Optional.of("123");
if (o1.isPresent()) {System.out.println(o1.get());
}

其它方法

Optional<Object> o2 = Optional.ofNullable(null);
String s = (String) o2.orElse("45");Optional<String> o1 = Optional.of("123");
o1.ifPresent(str -> System.out.println("has value"));Optional<String> o4 = Optional.of("ABC");
System.out.println(o4.map(String::toLowerCase).get());

3日期时间API

旧版日期时间API存在设计不合理、非线程安全、时区处理麻烦等问题

3.1日期时间类

LocalDate

LocalDate now = LocalDate.now();
LocalDate localDate = LocalDate.of(2024, 6, 1);

LocalTime

LocalTime now = LocalTime.now();
LocalTime localTime = LocalTime.of(14, 10, 10);

LocalDateTime

LocalDateTime now = LocalDateTime.now();
LocalDateTime localDateTime = LocalDateTime.of(2024, 1, 1, 10, 10, 9);

修改

LocalDateTime now = LocalDateTime.now();
System.out.println(now.withHour(20));

增加或减少

LocalDateTime now = LocalDateTime.now();
System.out.println(now.plusYears(1));
System.out.println(now.minusDays(10));

比较

LocalDateTime now = LocalDateTime.now();
LocalDateTime localDateTime = LocalDateTime.of(2024, 1, 1, 10, 10, 9);
System.out.println(now.isAfter(localDateTime));
System.out.println(now.isBefore(localDateTime));
System.out.println(now.isEqual(localDateTime));

3.2时间格式化与解析

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(now.format(dtf));
System.out.println(LocalDateTime.parse("2024-01-01 10:00:00", dtf));

3.3Instant

表示时间戳

Instant now = Instant.now();
System.out.println(now);
System.out.println(now.plusSeconds(10));
System.out.println(now.minusSeconds(5));
System.out.println(now.getNano());

3.4日期时间差

后面减去前面

时间差

LocalTime now = LocalTime.now();
LocalTime localTime = LocalTime.of(23, 10, 10);
Duration duration = Duration.between(now, localTime);
System.out.println(duration.toHours());
System.out.println(duration.toMinutes());
System.out.println(duration.getSeconds());

日期差

LocalDate now = LocalDate.now();
LocalDate localDate = LocalDate.of(2024, 6, 1);
Period period = Period.between(localDate, now);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());

3.5时间调整

LocalDateTime now = LocalDateTime.now();
System.out.println(now.with(TemporalAdjusters.firstDayOfNextYear()));

3.6设置时区

获取所有时区

Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();

标准时区

ZonedDateTime.now(Clock.systemUTC())

默认时区

ZonedDateTime.now()

指定时区

ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))

修改时区、时间

ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
zonedDateTime.withZoneSameInstant(ZoneId.of("Europe/Monaco"))

修改时区、不改时间

ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
zonedDateTime.withZoneSameLocal(ZoneId.of("Europe/Monaco"))

4重复注解与类型注解

4.1重复注解

@Config("abc")
@Config("def")
public class RepeatAnnotationDemo {public static void main(String[] args) {Config[] annotations = RepeatAnnotationDemo.class.getAnnotationsByType(Config.class);for (Config config : annotations) {System.out.println(config);}}
}@Retention(RetentionPolicy.RUNTIME)
@interface Configs {Config[] value();
}@Repeatable(Configs.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Config {String value();
}

4.2类型注解

@Target元注解新增了两种类型

TYPE_PARAMETER:可以写在类型参数的声明语句

public class TypeAnnotationDemo<@Type T> {
}@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@interface Type {
}

TYPE_USE:可以在任何用到类型的地方使用

public class TypeAnnotationDemo {@Type2private int i = 5;public int sum(@Type2 int a, @Type2 int b) {return a + b;}
}@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface Type2 {
}

源码仓库:gitee

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

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

相关文章

concurrent.futures的超时

concurrent.futures模块中的ThreadPoolExecutor和ProcessPoolExecutor类允许您在多线程或多进程环境中执行函数&#xff0c;并提供了超时功能。以下是如何使用这些执行器以及如何实现超时的具体代码案例。 使用ThreadPoolExecutor实现超时 import concurrent.futures import …

VUE2.7项目配置webpack打包-详细操作步骤

一、Webpack简介 Webpack是一个打包工具&#xff0c;可以把JS、CSS、Node Module、Coffeescrip、SCSS/LESS、图片等都打包在一起&#xff0c;因此&#xff0c;现在几乎所有的SPA项目、JS项目都会用到Webpack。 官网&#xff1a;https://webpack.js.org GitHub为https://git…

error 12154 received logging on to the standby报错处理

错误 处理方法 该参数不是主库的servicename &#xff08;低级错误&#xff09; SQL> alter system set log_archive_dest_2 SERVICEstandby ASYNC VALID_FOR(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAMEstandby; System altered. 观察主库日志: 备库日志: 该问题会影…

vue2自定义指令

本节目标 快速入门v-loading 快速入门 指令对比 基本语法 使用: v-指令名"指令值"定义: 通过 directives 局部定义或者全局定义通过事件对象 el 可以拿到指令所在元素通过形参 binding 可以拿到指令的传值通过update钩子, 可以监听指令值的变化,进行更新操作 局部…

C++进阶:继承

文章目录 继承的概念继承的定义方式继承关系和访问限定符基类和派生类对象的赋值转换继承中的作用域派生类中的默认成员函数构造函数拷贝构造函数赋值拷贝函数析构函数 总结 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允…

一个开源的Office软件,很离谱的办公神器

你们平时用的办公软件是哪一个&#xff1f;今天给大家分享的是一个“进阶版”office工具ONLY OFFICE&#xff0c;不仅支持Windows、Mac、ios, 安卓等全平台满足你的日常所需&#xff0c;更是提供了大量开挂般的功能。 1、打工人省金币 你们平时使用办公软件最头疼的问题是什么…

第1章Hello world 3/5:Cargo.lock:确保构建稳定可靠:运行第一个程序

讲动人的故事,写懂人的代码 1.6 Cargo.lock:确保构建稳定可靠 “看!”席双嘉一边指着屏幕一边说,“终端窗口提示符的颜色,从绿变黄了。这就意味着代码在上次提交后有点变化。” 赵可菲:“但是我们只是运行了程序,代码应该没动呀。” 席双嘉敲了下git status -uall,这…

PawSQL优化 | 分页查询太慢?别忘了投影下推

​在进行数据库应用开发中&#xff0c;分页查询是一项非常常见而又至关重要的任务。但你是否曾因为需要获取总记录数的性能而感到头疼&#xff1f;现在&#xff0c;让PawSQL的投影下推优化来帮你轻松解决这一问题&#xff01;本文以TPCH的Q12为案例进行验证&#xff0c;经过Paw…

高考志愿填报的技巧和方法

高考过后&#xff0c;最让家长和学生需要重视的就是怎样填报志愿。高考完和出成绩之前有一段很长的时间&#xff0c;而成绩出来之后往往报考的时间非常的紧张。在很短的时间内&#xff0c;高考的学生和他的家长要综合高考的成绩&#xff0c;考虑院校&#xff0c;专业&#xff0…

Vue中的组件通信

父向子通信 1.定义props 子组件中&#xff0c;定义期望接收的属性。例如&#xff0c;在子组件的script部分&#xff1a; export default {props: {message: String // 假设父组件要传递一个字符串类型的数据} } 2.传递数据 在父组件的模板中&#xff0c;通过属性绑定的方式将…

分享: 动图网站

Stickers for iOS & Android | GIPHY 这个网站有一些外国的制作的动图

OOP面试问题 - C#

文章概述 背景问题答案概括 背景 以下是最流行的 OOP面试问题和答案的列表。这些 OOPS 面试问题适用于初学者和专业 C# 开发人员。 问题 什么是对象&#xff1f;什么是封装&#xff1f;什么是抽象&#xff1f;什么是继承&#xff1f;哪些是访问说明符&#xff1f;如何在 C…

PHP实现一个简单的接口签名方法以及思路分析

文章目录 签名生成说明签名生成示例代码签名校验示例代码 签名生成说明 B项目需要调用A项目的接口&#xff0c;由A项目为B项目分配 AccessKey 和 SecretKey&#xff0c;用于接口加密&#xff0c;确保不易被穷举&#xff0c;生成算法不易被猜测。 最终需要确保包含签名的参数只…

2 程序的灵魂—算法-2.4 怎样表示一个算法-2.4.6 用计算机语言表示算法

我们的任务是用计算机解题&#xff0c;就是用计算机实现算法&#xff1b; 用计算机语言表示算法必须严格遵循所用语言的语法规则。 【例 2.20】求 12345 用 C 语言表示。 main() {int i,t; t1; i2; while(i<5) {tt*i; ii1; } printf(“%d”,t); } 【例 2.21】求级数的…

12_1 Linux Yum进阶与DNS服务

12_1 Linux Yum进阶与DNS服务 文章目录 12_1 Linux Yum进阶与DNS服务[toc]1. Yum进阶1.1 自定义yum仓库1.2 网络Yum仓库 2. DNS服务2.1 为什么要使用DNS系统2.2 DNS服务器的功能2.3 DNS服务器分类2.4 DNS服务使用的软件及配置2.5 搭建DNS服务示例2.6 DNS特殊解析 1. Yum进阶 1…

32-读取Excel数据(xlrd)

本篇介绍如何使在python中读取excel数据。 一、环境准备 先安装xlrd模块&#xff0c;打开cmd&#xff0c;输入 pip install xlrd 在线安装。 二、基本操作 import xlrd# 打开excel表格 data xlrd.open_workbook(test.xlsx)# 2.获取sheet表格 # 方式一&#xff1a;通过索引顺…

RocketMq详解:二、SpringBoot集成RocketMq

在上一章中我们对Rocket的基础知识、特性以及四大核心组件进行了详细的介绍&#xff0c;本章带着大家一起去在项目中具体的进行应用&#xff0c;并设计将其作为一个工具包只提供消息的分发服务和业务模块进行解耦 在进行本章的学习之前&#xff0c;需要确保你的可以正常启动和…

【算法篇】滑动窗口的最大值JavaScript版

滑动窗口的最大值 题目描述&#xff1a; 给定一个长度为 n 的数组 num 和滑动窗口的大小 size &#xff0c;找出所有滑动窗口里数值的最大值。 例如&#xff0c;如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3&#xff0c;那么一共存在6个滑动窗口&#xff0c;他们的最大值…

Linux Kernel入门到精通系列讲解(RV-Kernel 篇) 5.4 添加GPU和Framebuffer显示设备

1. 概述 上一章节我们已经成功的移植完busybox,到此,我们已经把我们Naruto-Pi的基本功能全部实现了,接下来,我们会不断探索,引入一些高级驱动,哇咔咔,真厉害,本章节比较简单,我们使用之前我们的8组virtio,我们就用其中一组模拟GPU,由于GPU我没深入了解过,所以我们…

[FFmpeg学习]初级的SDL播放mp4测试

在之前的学习中&#xff0c;通过AVFrame来保存为图片来认识了AVFrame&#xff0c; [FFmpeg学习]从视频中获取图片_ffmpeg 获取图片-CSDN博客 在获取到AVFrame时&#xff0c;还可以调用SDL方法来进行展现&#xff0c;实现播放效果。 参考资料 SDL&#xff0c;ffmpeg实现简单…