JAVA8的新特性——Stream

news2025/2/21 19:58:14

JAVA8的新特性——Stream

在这里插入图片描述

在这个深夜写下这篇笔记,窗外很安静,耳机里是《季节更替》,我感触还不是很多,当我选择封面图片的时候才发现我们已经渐渐远去,我们都已经奔赴生活,都在拼命想着去换一个活法,六月就要真的结束这段关系,好怀念校园的那段日子,我们不用去思考以后,在这个象牙塔里幻想一份感情,互相玩笑,走出来了,就真的远去!愿我们所得皆所愿,不被生活磨平了棱角,聪哥,腿哥,伟哥,吕子,帆子,还有此刻读到文章的你,加油,我们一起向前冲!
——2023年5月15日凌晨 IT小辉同学

Java 8中引入的Stream是一种全新的数据处理方式,它使用简单而高效的方法对集合数据进行操作。下面对Stream进行详细介绍

什么是 Stream(引用菜鸟教程)

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现

Stream的用法

Stream是Java 8中针对集合数据的一种新的操作方式,使用了类似于SQL语句的流式操作方式。Stream由三部分构成:源、零个或多个中间操作、终止操作。
源是指Stream要处理的原始数据源,可以是Collection、Array、I/O资源等;
中间操作用来对数据进行转化、过滤、排序等操作,其中每一个中间操作都会返回一个新的Stream对象;
终止操作用来获取Stream处理结果。

Stream的特点

(1)流式操作:Stream提供了一种流式的操作方式,方便数据处理和转换;
(2)惰性求值:Stream使用惰性求值方式进行计算,只有在被终止操作时才会进行计算;
(3)并行处理:Stream支持并行处理,提高了处理大数据集的效率。

Stream的优缺点

优点:
(1)简洁:使用Stream可以让代码更加简洁易懂;
(2)高效:Stream支持惰性求值和并发处理,提高了处理效率;
(3)灵活:Stream提供了多种操作方式,可以适应不同的数据处理需求。

缺点:
(1)学习成本:Stream需要掌握一些新的操作方式,需要一定的学习成本;
(2)线程安全:并行处理时需要注意线程安全问题。

Stream的使用场景

Stream适用于处理大数据集和需要频繁进行转换、过滤、排序等操作的场景。例如,对于需要筛选和排序的订单列表或者用户列表等数据集合,Stream可以极大地提高处理效率和代码简洁度。

Stream的发展趋势

随着Java生态系统的不断发展,Stream也在不断完善和优化中。未来Stream可能会增加更多的功能和特性,同时也会进一步提升处理效率和优化用户体验。

总之,Stream是Java 8中非常重要的一个新特性,它为集合数据的处理提供了一种全新的方式,具有很多优点和适用场景。因此,熟练掌握Stream的各种用法和特点对Java开发者来说是非常重要的。

Java生成Stream

Java中可以通过多种方式来生成Stream,包括:

  1. 从集合中生成Stream:

可以使用Collection接口提供的stream()方法或parallelStream()方法来生成Stream对象。例如:

List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
  1. 从数组中生成Stream:

可以使用Arrays类提供的stream()方法或parallelStream()方法来生成Stream对象。例如:

int[] arr = new int[]{1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(arr);
  1. 使用Stream.of()方法生成Stream:

可以使用Stream类提供的of()方法来生成Stream对象。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
  1. 使用Stream.iterate()方法生成Stream:

可以使用Stream类提供的iterate()方法来生成Stream对象。该方法需要传入一个初始值和一个函数接口,用来生成无限长度的Stream。例如:

Stream<Integer> stream = Stream.iterate(1, n -> n + 1);
  1. 使用Stream.generate()方法生成Stream:

可以使用Stream类提供的generate()方法来生成Stream对象。该方法需要传入一个函数接口,用来生成无限长度的Stream。例如:

Stream<Double> stream = Stream.generate(Math::random);

总之,Java中可以通过多种方式来生成Stream对象,可以根据不同的需求选择不同的方式来生成Stream。

Stream中的filter过滤

filter()方法可以用于过滤出满足特定条件的元素。

具体来说,filter()方法会接收一个函数式接口Predicate<T>,该接口只有一个方法test(T t),该方法接受一个参数t,返回一个布尔值。当test()方法的返回值为true时,表示当前元素应该被保留;当返回值为false时,表示当前元素应该被过滤掉。

	/**
     * @Description 过滤掉apple这个字符串
     * @Author IT小辉同学
     * @Date 2023/05/14
     */
    @Test
    public void test1() {
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        //过滤掉apple这个字符串
        List<String> stringList =
                stream.filter(s -> !s.equals("apple"))
                        .collect(Collectors.toList());
        System.out.println("过滤掉apple这个字符串:"+stringList);
    }

    /**
     * @Description 过滤掉含字母a的字符串
     * @Author IT小辉同学
     * @Date 2023/05/14
     */
    @Test
    public void test2() {
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        //过滤掉含字母a的字符串
        List<String> stringList1=
                stream.filter(s -> !s.contains("a"))
                        .collect(Collectors.toList());
        System.out.println("过滤掉含字母a的字符串:"+stringList1);
    }

    /**
     * @Description 过滤掉含字母a和i的字符串
     * @Author IT小辉同学
     * @Date 2023/05/14
     */
    @Test
    public void test3() {
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        //过滤掉含字母a和i的字符串
        List<String> stringList1=
                stream.filter(s -> !s.contains("a")&&!s.contains("i"))
                        .collect(Collectors.toList());
        System.out.println("过滤掉含字母a和i的字符串:"+stringList1);
    }

注意:同一个Stream不可进行多次操作,否则报错

错误示例

List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        //过滤掉apple这个字符串
        List<String> stringList =
                stream.filter(s -> !s.equals("apple"))
                        .collect(Collectors.toList());
        System.out.println("过滤掉apple这个字符串:"+stringList);
 		//过滤掉含字母a和i的字符串
        List<String> stringList1=
                stream.filter(s -> !s.contains("a")&&!s.contains("i"))
                        .collect(Collectors.toList());
        System.out.println("过滤掉含字母a和i的字符串:"+stringList1);

报错情况

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
	at java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:94)
	at java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:618)
	at java.util.stream.ReferencePipeline$2.<init>(ReferencePipeline.java:163)
	at java.util.stream.ReferencePipeline.filter(ReferencePipeline.java:162)
	at com.demo.example.StreamDemo.main(StreamDemo.java:20)什么原因

详细解释

这个异常通常是因为对一个已经被操作或关闭的Stream进行了再次操作或关闭,导致Stream状态不正确,从而抛出IllegalStateException异常。解决这个问题的方法通常有以下几种:

  1. 避免在同一个Stream上进行多个终止操作:

即使多个终止操作被串联在一起,也只会执行最后一个终止操作。因此,在一个Stream对象上执行多个终止操作会导致Stream被关闭,从而引发IllegalStateException异常。如果需要对同一个Stream进行多个操作,可以将其保存到一个中间变量中,并对该中间变量进行操作。例如:

Stream<String> stream = list.stream();
stream = stream.filter(s -> s.length() > 5);
stream.forEach(System.out::println);
  1. 使用新建的Stream对象进行操作:

对于Stream对象的所有操作都会返回一个新的Stream对象,因此可以通过使用新建的Stream对象来避免对已经被操作或关闭的Stream进行操作。例如:

Stream<String> stream1 = list.stream();
Stream<String> stream2 = stream1.filter(s -> s.length() > 5);
stream2.forEach(System.out::println);
  1. 改用Stream.peek()方法:

peek()方法是一种类似于forEach()方法但不会关闭Stream的中间操作。可以通过使用peek()方法来进行调试和测试操作。例如:

Stream<String> stream = list.stream();
stream = stream.filter(s -> s.length() > 5).peek(System.out::println);
stream.forEach(System.out::println);

总之,如果出现了IllegalStateException异常,通常是因为对一个已经被操作或关闭的Stream进行了再次操作或关闭。可以通过避免在同一个Stream对象上进行多个终止操作、使用新建的Stream对象进行操作或改用Stream.peek()方法来解决这个问题。

Stream中的forEach遍历

forEach()方法是一种用于遍历Stream元素并对每个元素进行指定操作的终止操作方法。

forEach()方法接收一个Lambda表达式作为参数,该表达式会被应用到Stream中的每个元素上,用来执行指定的操作。该方法不返回任何值,只是将Lambda表达式应用到Stream中的每个元素上,从而实现对Stream的遍历操作。

 /**
     * @Description 简单遍历
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test4(){
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        stream.forEach(System.out::println);
    }
    /**
     * @Description 遍历去除含有字母b的字符串
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test5(){
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        Stream<String> stream = list.stream();
        stream.filter(s -> !s.contains("b"))
                .forEach(System.out::println);
    }
    /**
     * @Description 遍历去除含有字母b和i的字符串并且添加到arrayList
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test6(){
        List<String> list = Arrays.asList("apple", "banana", "orange","cherry","Hami");
        ArrayList<String> arrayList=new ArrayList<>();
        Stream<String> stream = list.stream();
        stream.filter(s -> !s.contains("b"))
                .forEach(arrayList::add);
        System.out.println(arrayList);
    }

Stream中的map映射

map操作可以将Stream中的每个元素映射到另一个元素上,并返回一个新的Stream。

map操作的语法如下:

Stream<T> map(Function<? super T, ? extends U> mapper)

其中,T是Stream中的元素类型,U是映射后的元素类型。mapper是一个函数式接口,它接受一个元素作为输入,并返回一个新的元素作为输出。

map操作的作用是将Stream中的每个元素映射到另一个元素上,并返回一个新的Stream。这个操作非常灵活,可以用于很多不同的场景。

   /**
     * @Description 使用 map 输出了元素对应的平方数
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test7() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers
                .stream()
                .map(i -> i * i)
                .collect(Collectors.toList());
        System.out.println(squaresList);
    }
    /**
     * @Description 使用 map 输出了元素对应的平方数(去重)
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test8() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers
                .stream()
                .map(i -> i * i)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(squaresList);
    }
    /**
     * @Description 使用 map 输出了元素对应的平方数(去重并且排序)
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test9() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers
                .stream()
                .map(i -> i * i)
                .distinct()
                .sorted()
                .collect(Collectors.toList());
        System.out.println(squaresList);
    }
    /**
     * @Description 使用 map 输出了元素对应的平方数(去重并且排序,限制个数)
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test10() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers
                .stream()
                .map(i -> i * i)
                .distinct()
                .sorted()
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(squaresList);
    }

Stream中的parallel并行程序

parallel操作可以将Stream中的每个元素并行处理,并返回一个新的Stream。

parallel操作的语法如下:

Stream<T> parallel()

其中,T是Stream中的元素类型。

parallel操作的作用是将Stream中的每个元素并行处理,并返回一个新的Stream。这个操作可以用于处理大量数据,提高处理效率。

需要注意的是,parallel操作会创建一个新的线程来处理每个元素,这可能会导致性能开销。因此,在使用parallel操作时,需要根据具体的情况来评估其性能开销,并进行适当的优化。

    /**
     * @Description 获取空字符串的数量
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test11() {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        // 获取空字符串的数量
        long count = strings
                .parallelStream()
                .filter(string -> string.isEmpty())
                .count();
        System.out.println(count);
    }
    /**
     * @Description 去除空字符串转换为数组
     * @Author IT小辉同学
     * @Date 2023/05/15
     */
    @Test
    public void test12() {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        // 获取空字符串的数量
        List<String> stringList = strings
                .parallelStream()
                .filter(string ->!string.isEmpty())
                .collect(Collectors.toList());
        System.out.println(stringList);
    }

Stream中的Collectors聚合操作

Stream中的Collectors聚合操作是一种用于对流数据进行处理的方法,它可以将流中的元素按照指定的规则进行分组、过滤、映射等操作,最终生成一个新的流。

以下是一些常见的聚合操作:

  1. toList():将流中的元素收集到一个List中。
List<Integer> list = stream.collect(Collectors.toList());
  1. toSet():将流中的元素收集到一个Set中,去重。
Set<Integer> set = stream.collect(Collectors.toSet());
  1. toMap():将流中的元素按照指定的键值对进行分组,并返回一个Map对象。
Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), Function.identity()));
  1. maxBy():按照指定的属性或方法对流中的元素进行比较,返回最大值。
Optional<Integer> max = stream.max(Comparator.comparingInt(i -> i));
  1. minBy():按照指定的属性或方法对流中的元素进行比较,返回最小值。
Optional<Integer> min = stream.min(Comparator.comparingInt(i -> i));
  1. sum():对流中的数字类型元素进行求和。
long sum = stream.mapToLong(i -> i).sum();
  1. count():统计流中元素的数量。
long count = stream.count();
  1. average():计算流中数字类型元素的平均值。
double average = stream.mapToDouble(i -> i).average().orElse(0d);
  1. filter():根据指定的条件过滤流中的元素。
stream.filter(i -> i > 10).forEach(System.out::println); // 输出大于 10 的元素
  1. distinct():去重操作,返回不同的元素组成的流。
List<Integer> distinctList = stream.distinct().collect(Collectors.toList()); // 去重后生成 List 集合

使用Collectors可以简化代码,提高开发效率,同时也可以实现更加灵活的数据处理方式。

Stream中的统计函数

另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

好的,以下是Stream中的统计函数介绍:

  1. count():统计流中元素的数量。
long count = stream.count();
  1. min():返回流中最小的元素。
Optional<T> min = stream.min(Comparator.comparing(i -> i));
  1. max():返回流中最大的元素。
Optional<T> max = stream.max(Comparator.comparing(i -> i));
  1. sum():对流中的元素进行求和。
long sum = stream.mapToLong(i -> i).sum();
  1. average():计算流中元素的平均值。
double average = stream.mapToDouble(i -> i).average().orElse(0d);
  1. distinct():返回去重后的元素列表。
List<T> distinctList = stream.distinct().collect(Collectors.toList()); // 去重后生成 List 集合
  1. anyMatch():判断流中是否存在至少一个满足条件的元素。
boolean anyMatch = stream.anyMatch(i -> i > 10); // 判断是否存在大于 10 的元素
  1. allMatch():判断流中的所有元素是否都满足条件。
boolean allMatch = stream.allMatch(i -> i > 10); // 判断所有元素是否都大于 10
  1. noneMatch():判断流中是否不存在满足条件的元素。
boolean noneMatch = stream.noneMatch(i -> i < 10); // 判断是否不存在小于 10 的元素

一个小例子结束学习之旅

数字平方排序(倒叙)输出

字符串转 map 输出

public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        // List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
        List<Integer> squaresList = numbers.stream()
                .map(i -> i * i)
                .sorted((x, y) -> y - x)
                .collect(Collectors.toList());
        // squaresList.forEach(System.out::println);
        squaresList.forEach(num -> {
            num++;
            System.out.println(num);
        });

        List<String> strList = Arrays.asList("a", "ba", "bb", "abc", "cbb", "bba", "cab");
        Map<Integer, String> strMap = new HashMap<Integer, String>();

        strMap = strList.stream()
                .collect( Collectors.toMap( str -> strList.indexOf(str), str -> str ) );

        strMap.forEach((key, value) -> {
            System.out.println(key+"::"+value);
        });
    }

sorted()方法的第二个参数是一个比较器(Comparator),用于指定排序规则。比较器的逻辑接受两个参数,分别代表要比较的两个元素,返回一个负数、零或正数,表示第一个参数小于、等于或大于第二个参数。
在sorted((x, y) -> y - x)中,括号内的第一个参数x和第二个参数y分别代表要比较的两个元素。比较器的逻辑是按照从每个元素到自身的降序差值进行比较,即用第二个元素减去第一个元素,得到的结果就是它们之间的大小关系。如果结果为负数,则说明第一个元素小于第二个元素;如果结果为0,则说明它们相等;如果结果为正数,则说明第一个元素大于第二个元素。
因此,sorted((x, y) -> y - x)实际上定义了一个从每个元素到自身的降序差值的比较器,用于对列表进行排序操作。

前辈的文章推荐(如果感觉对于个人这篇文章已经透彻,可以看看前辈的文章,本人学习之后,方知自我之浅薄)

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

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

相关文章

Kubernetes 二进制部署高可用集群

概述 在私有局域网内完成Kubernetes二进制高可用集群的部署 ETCD Openssl > ca 证书 Haproxy Keepalived Kubernetes 主机规划 序号名字功能VMNET 1备注 1备注 2备注 3 备注 4备注 50orgin界面192.168.164.10haproxykeepalived1reporsitory仓库192.168.164.16yum 仓库re…

哈工大C语言大作业-学生成绩管理系统

哈工大C语言大作业-学生成绩管理系统 完整项目地址&#xff1a;https://github.com/944613709/Student-Performance-Management-System-ByC 说明 l 设计了学生成绩管理系统&#xff0c;来实现对于学生数据的录入统计等各个功能l 进入主菜单之前执行音效播放l menu主菜单中显…

C语言基础知识:C语言中的控制语句

目录 1. 条件判断语句 if(…) {…} if(…) {…} else {…} if(…) {…} else if(…) {…} … else if(…) {…} else {…} switch() {case …: …; case …: …; … default: …;} 2、循环语句 while语句 do while语句 for语句 3、循环体中的跳转语句 break语句。 c…

consul集群部署-linux

一.前言 1. Consul架构 consul是分布式、高可用的系统&#xff0c;下图是单数据中心的部署架构 2. Consul特性 服务发现&#xff1a;解决在分布式环境中&#xff0c;如何找到可用的服务地址的问题&#xff0c;支持通过DNS和HTTP查询服务地址。健康检查&#xff1a;定时监控服务…

如何正确学习网络安全(黑客)?看到就是赚到!

一、前言 本人10 年工作经验&#xff0c; 擅长 Web 安全攻防、渗透领域&#xff0c; 在金融领域的安全有丰富的实战经验。从事在线教育 3 年多培养学员过万&#xff0c;讲解清晰透彻&#xff0c;课程干货内容多&#xff0c;辅导学员耐心细致 那我们该如何正确学习网络安全&am…

[学习笔记] [机器学习] 5. 逻辑回归(逻辑回归、混淆矩阵、分类评估指标、ROC曲线、AUC指标、类别不均衡问题)

视频链接数据集下载地址&#xff1a;无需下载 本文学习目标&#xff1a; 知道逻辑回归的损失函数、优化方法知道逻辑回归的应用场景应用LogisticRegression实现逻辑回归预测知道精确率、召回率等指标的区别知道如何解决样本不均衡情况下的评估会绘制ROC曲线图形 1. 逻辑回归…

Linux——Linux的基本指令

作者&#xff1a;几冬雪来 时间&#xff1a;2023年5月15日 内容&#xff1a;Linux基本指令讲解 目录 前言&#xff1a; 1. 什么是操作系统&#xff1a; 2.Linux操作系统&#xff1a; 3.Linux程序&#xff1a; 4.Linux基本指令&#xff1a; 1.ls&#xff1a; 作用&a…

Java基础 关键字与标识符

关键字(keyword) 定义:被 Java 语言赋予了特殊含义&#xff0c;用做专门用途的字符串(或单词) 这些单词已经被 Java 定义好 了。 特点:全部关键字都是小写字母。 关键字比较多&#xff0c;不需要死记硬背&#xff0c;学到哪里记到哪里即可。官方地址 1. 关键字一共 50 个&…

linux bonding 技术

文章目录 背景简介目录1. Bonding驱动简介1.1 配置并编译支持bonding的内核1.2 安装ifenslave控制工具 2. Bonding驱动选项3. 配置Bonding设备3.1 使用Sysconfig配置3.1.1 利用Sysconfig使用DHCP3.1.2 利用Sysconfig配置多个Bonds 3.2 使用Initscripts配置3.2.1 利用Initscript…

Linux篇3

Shell常用命令 0. Shell介绍1. 帮助命令1.0 help&#xff1a;获取内置命令帮助信息1.1 man&#xff1a;获取帮助信息 2. 文件目录相关2.1 pwd&#xff1a;打印当前工作目录的绝对路径2.2 cd&#xff1a;切换工作目录2.3 ls&#xff1a;列出目录内容2.4 mkdir&#xff1a;创建空…

Java小游戏之贪吃蛇

文章目录 一&#xff1a;窗口的绘制1.1 定义窗口类——SnakeGame1.2 设置窗口的参数1.3 启动main方法 二&#xff1a;窗口网格的绘制2.1 重写paint方法2.1.1 为什么要重写paint方法2.1.2 实现方式 2.2 Graphics2.3 设置网格线的参数 三&#xff1a;游戏物体父类的创建——Snake…

Swagger之集成与用法

简介 Swagger 是一个规范且完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务&#xff1b; 作用 1.接口的文档在线生成 2.功能测试 SpringBoot集成Swagger 1.创建一个普通的SpringBoot项目&#xff0c;支持web应用 2.pom中加入Maven依赖 <depe…

K8S的的就绪探针readinessProbe 和存活探针livenessProbe

就绪探针&#xff1a;readinessProbe 什么是readinessProbe readinessProbe&#xff1a; 当Pod需要开始接收流量时&#xff0c;“kubelet” 将定期检查 readinessProbe&#xff0c;如果该probe处于成功状态&#xff0c;则容器视为就绪&#xff0c;并将 Pod 标记为已就绪状态。…

栈的基本操作详细介绍 看了就会!!!

文章目录 栈的介绍栈的概念栈的结构 栈的实现&#xff08;动态数组实现&#xff09;初始化栈入栈出栈获取栈顶元素判断栈是否为空获取栈中有效元素的个数销毁栈 栈的介绍 栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进…

机器学习期末复习 决策树相关

决策树基本原理&#xff1a;基于信息增益、增益率与基尼系数的划分选择&#xff0c;预剪枝与后剪枝&#xff0c;多变量决策树以及决策树优缺点概述 如何避免决策树过拟合&#xff1f; 预剪枝和后剪枝 预剪枝&#xff1a; 1.生成结点&#xff0c;根据信息增益选出最优划分属…

玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架

一、前言 上一篇我们分析了gtest的一些内部实现&#xff0c;总的来说整体的流程并不复杂。本篇我们就尝试编写一个精简版本的C单元测试框架&#xff1a;nancytest &#xff0c;通过编写这个简单的测试框架&#xff0c;将有助于我们理解gtest。 二、整体设计 使用最精简的设计…

Docker下Gitlab配置私有证书

Docker下Gitlab配置私有证书 1 创建私有证书※2 内网穿透配置&#xff08;可选&#xff09;3 Gitlab 配置私有证书3.1 新增存储HTTPS证书文件夹3.2 启动容器3.3 开放HTTPS端口3.4 设置IP、端口3.5 配置邮箱3.6 让配置生效3.7 访问 1 创建私有证书 参考 制作HTTPS私有证书 —HT…

玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制

一、前言 gtest提供了多种事件机制&#xff0c;非常方便我们在案例之前或之后做一些操作。总结一下gtest的事件一共有3种&#xff1a; 1. 全局的&#xff0c;所有案例执行前后。 2. TestSuite级别的&#xff0c;在某一批案例中第一个案例前&#xff0c;最后一个案例执行后。…

【STM32】基础知识 第十四课 串口通信: 深入探究与应用

【STM32】基础知识 第十四课 串口通信: 深入探究与应用 概述串口通信的基本原理串行通信 & 并行通信串行通信并行通信串行 vs 并行 单工/半双工/全双工单工通信半双工通信全双工通信总结 同步通信/异步通信同步通信异步通信波特率 常见的串行通信接口STM32 串口配置STM32 串…

linux pl320 mbox控制器驱动分析-(3) pl320驱动代码分析

linux pl320 mbox控制器驱动分析-&#xff08;3&#xff09;pl320驱动代码分析 1 pl320 mbox控制器宏定义2 初始化接口3 ipc_handler mbox中断处理函数4 数据的收发4.1 数据发送4.2 数据接收4.3 中断发送接收测试代码 5 设置以及清除远端目的core5.1 设置远端目的core5.2 清除远…