jdk8新特性(Lambda、Steam、函数式接口)

news2024/11/22 15:32:34

JDK8新特性

  • JDK8新特性
    • Lambda表达式
    • 函数式(Functional)接口
    • 方法引用与构造器引用
      • 方法引用
      • 构造器引用
    • 强大的 StreamAPI
        • 创建Stream方式
        • Stream 的中间操作
        • Stream 的终止操作
    • Optional 类

Java 8 (又称为jdk 1.8)是Java语言开发的一一个主要版本。
Java 8是oracle公司于2014年3月发布,可以看成是自Java5以来最具革命性的版本。Java 8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性。

特点

  • 速度更快

  • 代码更少(增加了新的语法: Lambda 表达式)

  • 强大的Stream API

  • 便于并行最大化减少空指针异常: Optional

  • Nashorn引擎,允许在JVM.上运行JS应用

Lambda表达式

Lambda初体验

-> : Lambda 操作符、箭头操作符

左边:Lambda形参列表(就是抽象方法里的形参)

右边:Lambda 方法体(就是重写抽象方法的方法体)

   @Test
    public void test1() {
        // 普通写法
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("普通写法");
            }
        };
        r1.run();

        System.out.println("*********************************");
        // Lambda方式
        Runnable r2 = () -> System.out.println("Lambda写法");
        r2.run();
    }

    // 普通方式
    @Test
    public void test2() {

    }

    @Test
    public void test3() {
        Comparator<Integer> c1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };
        System.out.println(c1.compare(10, 21));

        System.out.println("*********************");
        Comparator<Integer> c2 = (o1, o2) -> {
            return Integer.compare(o1, o2);
        };
        System.out.println(c2.compare(21, 2));
    }

Lambda 表达式的使用

  1. 形参可以省略参数类型,编译器自动进行 “类型推断”
  2. Lambda 若只需要一个参数时,参数的小括号可以省略
    @Test
    public void test4() {
        Consumer<String> c1 = s -> {
            System.out.println(s);
        };
        c1.accept("省略参数小括号");
    }
  1. Lambda 方法体有多条语句时,允许有 return 返回值

  2. Lambda 方法体只有一条语句时,return 和 大括号 都可以省略

    @Test
    public void test5() {
        Comparator<Integer> c2 = (o1, o2) -> Integer.compare(o1, o2);
        System.out.println(c2.compare(21, 2));
    }

Lambda表达式的本质: 就是接函数式口的实例,重写接口中的方法

函数式(Functional)接口

如果一个接口中,只声明了一个抽象方法,该接口就是函数式接口

  • 只包含一个抽象方法的接口,称为函数式接口。
  • 你可以通过Lambda表达式来创建该接口的对象。 (若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)
  • 我们可以在一一个接口.上使用==@FunctionalInterface==注解,这样做可以检查它是否是-一个函数式接口。同时javadoc也会包含一条声明, 说明这个接口是一个函数式接口。
  • 在java.util.function包下定 义了Java 8的丰富的函数式接口

Java提供的四大函数式接口:

image-20221103084722839

Consumer接口:

    @Test
    public void test() {
        // 普通写法
        method1(200d, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("消费了 " + aDouble);
            }
        });
        System.out.println("********************************");
        // Lambda 写法
        method1(300d, money -> System.out.println("消费了 " + money));

    }

    public void method1(Double money, Consumer<Double> consumer) {
        consumer.accept(money);
    }

Predicate接口:

    @Test
    public void test2() {
        List<String> lists = new ArrayList<>();
        lists.add("普京");
        lists.add("北京");
        lists.add("西京");
        lists.add("南京");
       // 普通写法
       List<String> list = method2(lists, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });
        System.out.println(list);
        System.out.println("*************************************");
        // Lambda 写法
        List<String> list1 = method2(lists,s -> s.contains("京"));
        System.out.println(list1);
    }

    public List<String> method2(List<String> list, Predicate<String> pre) {
        ArrayList<String> newList = new ArrayList<>();
        for (String s : list) {
            if (pre.test(s)) {
                newList.add(s);
            }
        }
        return newList;
    }

其他接口:

image-20221103090106993

方法引用与构造器引用

方法引用

  • 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用 !
  • 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一一个语法糖。

要求 : 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致 !(针对情况一和情况二)

格式: 使用操作符 “::” 将类(或对象)与方法名分隔开来。

  • 如下三种主要使用情况:

    ➢对象::实例方法名

    ➢类::静态方法名

    ➢类::实例方法名 (特殊)

个人理解

​ Lambda 和 方法引用都可以看做是函数式接口的实例,主要目的都是为了重写接口中的抽象方法。

​ Lambda 重写抽象方法主要是自己编写方法体

​ 方法引用重写抽象方法主要是 使用 方法的引用 编写方法体。但是具体是什么样的方法是由要求的。

代码演示:

   // 情况一:对象::实例方法
    @Test
    public void test1() {
        // Lambda 方式
        Consumer<String> con = s -> System.out.println(s);
        con.accept("Lambda方式");

        // 方法引用
        // void accept(T t);
        // void println(T t)
        // 接口中的抽象方法的形参列表和返回值,与方法引用的方法形参列表、返回值都一样。
        Consumer<String> con1 = System.out::println;
        con1.accept("方法引用");
    }

    // 情况二:类::静态方法
    @Test
    public void test3() {
        // Lambda方式
        // int compare(T o1, T o2);
        //  static int compare(int x, int y)
        Comparator<Integer> com1 = (o1,o2) -> Integer.compare(o1,o2);
        System.out.println(com1.compare(21, 22));
        // 方法引用的方式
        Comparator<Integer> com2 = Integer::compare;
        System.out.println(com1.compare(23, 22));
    }

    // 情况三: 类::实例方法(比较特殊)
    @Test
    public void test4() {
        // Lambda 方式
        // int compare(T o1, T o2);
        // int compareTo(String anotherString)
        // 这种情况比较特殊,接口中抽象方法的形参列表和方法引用中的形参列表不一样
        // 但是该方法是通过另外一个参数调用的,因此也可以使用方法引用
        Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
        // 方法引用方式
        Comparator<String> com2 = String::compareTo;
    }

情况三比较特殊:当方法引用中的形参列表中的一个参数作为方法的调用者时,也可以使用方法引用

构造器引用

  // 传一个参数
    @Test
    public void test1() {
        // Lambda 方式
        Function<Long,User> fun1 = id -> new User(id);
        System.out.println(fun1.apply(10001L));

        // 构造器引用
        Function<Long,User> fun2 = User::new;
        System.out.println(fun2.apply(10002L));

    }

    // 传俩个参数
    @Test
    public void test2() {
        // Lambda 方式
        BiFunction<Long,String,User> bifun1 = (id,name) -> new User(id,name);
        System.out.println(bifun1.apply(10L, "李四"));
        // 构造器引用
        BiFunction<Long,String,User> bifun2 = User::new ;
        System.out.println(bifun2.apply(20L, "王五"));
    }

    // 数组引用: 将数组看成一个类,和构造器引用一样
    @Test
    public void test3() {
        // Lambda 方式
        Function<Integer,String[]> fun1 = length -> new String[length];
        System.out.println(Arrays.toString(fun1.apply(5)));
        // 数组引用
        Function<Integer,String[]> fun2 = String[]::new;
        System.out.println(Arrays.toString(fun2.apply(10)));
    }

强大的 StreamAPI

Java8中有两大最为重要的改变。第一一个是Lambda表达式;另外- 一个则是Stream API。|

  • Stream API ( java.util.stream)把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充
  • Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。

简言之,StreamAPl 提供了一种高效且易于使用的处理数据的方式。

为什么要使用 Stream Api ?

  • 实际开发中,项目中多数数据源都来自于Mysq|l,Oracle等。 但现在数据源可以更多了,有MongDB,Radis等, 而这些NoSQL的数据就需要Java层面去处理。

  • Stream和Collection集合的区别: Collection是一种静态的内存数据结构,而Stream是有关计算的。前者是主要面向内存,存储在内存中,后者主要是面向CPU,通过CPU实现计算。

Stream到底是什么呢?

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,Stream讲的是计算!”

注意

  • Stream 自己不会存储元素。
  • Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream.
  • Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream的操作三个步骤

  • 创建Stream
    • 一个数据源(如:集合、数组),获取一个流
  • 中间操作
    • 一个中间操作链,对数据源的数据进行处理
  • 终止操作(终端操作)
    • 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

image-20221103120252231

创建Stream方式

通过集合

Java8中的Collection接口被扩展,提供了两个获取流的方法:

default Stream stream(): 返回一个顺序流
default Stream parallelStream(): 返回一一个并行流

    @Test
    public void test1() {
        // 方式一:通过集合
        List<User> userList = User.getUserList();
        Stream<User> stream = userList.stream();

        // 返回一个并行流
        Stream<User> parallelStream = userList.parallelStream();
    }

通过数组

Arrays 中定义了获取 stream 的方法:

public static <T> Stream<T> stream(T[] array) {}
    @Test
    public void test2() {
        // 方式二:通过数组
        User[] userArray = User.getUserArray();
        Stream<User> stream = Arrays.stream(userArray);
    }

通过Stream的of

    @Test
    public void test3() {
        // 通过Stream的of
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
    }

可以使用静态方法Stream.iterate()和Stream.generate(),创建无限流

public static Stream iterate(final T seed, final UnaryOperator f) 迭代
public static Stream generate(Supplier s) 生成

    @Test
    public void test4() {
        // 方式四: 通过 iterate 和 generate
        // 获取20以内的偶数
        Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
        // 生成数据
        Stream<List<User>> generate = Stream.generate(User::getUserList);
    }

Stream 的中间操作

筛选与切片

image-20221103124713511

代码演示:

   // 1. 筛选与切片
    @Test
    public void test1() {
        Stream<User> stream = User.getUserList().stream();
        // Stream<T> filter(Predicate<? super T> predicate); 从流中排除某些元素
        // forEach: 流的终止操作
        // 排除工资低于 2000 的
        stream.filter(user -> user.getSalary() > 2000).forEach(System.out::println);

        System.out.println("*****************************************************");
        Stream<User> stream1 = User.getUserList().stream();
        // Stream<T> limit(long maxSize); 截断流,是其元素不得超过指定数
        stream1.limit(2).forEach(System.out::println);
        // 报错:java.lang.IllegalStateException: stream has already been operated upon or closed
        // 流一旦执行终止操作就会关闭,想要在使用再重新创建一个流
        // stream1.limit(3).forEach(System.out::println);
        
        System.out.println("*****************************************************");
        Stream<User> stream2 = User.getUserList().stream();
        // Stream<T> distinct(); 筛选流,通过元素的的hashCode和equals方法去除重复元素
        stream2.distinct().forEach(System.out::println);

        System.out.println("*****************************************************");
        Stream<User> stream3 = User.getUserList().stream();
        // Stream<T> skip(long n); 跳过 n 个元素,若不足n个元素,则返回一个空流
        stream3.skip(3).forEach(System.out::println);
    }

映射

image-20221103172521778

    // 映射
    @Test
    public void test2() {
        List<User> users = User.getUserList();
        
        // <R> Stream<R> map(Function<? super T, ? extends R> mapper);
        Stream<Double> stream = users.stream().map(User::getSalary);
        System.out.println(stream);
    }
}

排序

image-20221103173335997

代码演示:

    @Test
    public void test1() {
        Stream<Integer> stream = Arrays.asList(2, 1, 33, 22, 11).stream();
        // Stream<T> sorted(); 按自然顺序排序
        stream.sorted().forEach(System.out::println);

        Stream<User> stream1 = User.getUserList().stream();
        //    Stream<T> sorted(Comparator<? super T> comparator); 自定义排序规则
        stream1.sorted(Comparator.comparingDouble(User::getSalary)).forEach(System.out::println);

    }

Stream 的终止操作

匹配与查找

boolean allMatch(Predicate<? super T> predicate);检查流中所有元素都匹配
boolean anyMatch(Predicate<? super T> predicate);检查流中元素是否至少有一个匹配
boolean noneMatch(Predicate<? super T> predicate);检查流中元素是否都不匹配
Optional findFirst();返回流中第一个元素
Optional findAny();返回流中最后一个元素
long count();返回流中的个数
Optional max(Comparator<? super T> comparator);返回流中最大的的元素
Optional min(Comparator<? super T> comparator);返回流中最小的元素
void forEach(Consumer<? super T> action);迭代遍历

代码演示:

 @Test
    public void test1() {
        List<User> users = User.getUserList();
        // boolean allMatch(Predicate<? super T> predicate); 检查流中是否所有元素都匹配
        // 检查是否所有的用户工资都大于 2000
        boolean allMatch = users.stream().allMatch(user -> user.getSalary() > 2000);
        System.out.println(allMatch);

        //  boolean anyMatch(Predicate<? super T> predicate); 检查流中是否有元素匹配上
        boolean anyMatch = users.stream().anyMatch(user -> user.getSalary() > 10000);
        System.out.println(anyMatch);

        // boolean noneMatch(Predicate<? super T> predicate); 检查流中是否都不匹配
        boolean noneMatch = users.stream().noneMatch(user -> user.getName().startsWith("王"));
        System.out.println(noneMatch);


        // Optional<T> findFirst(); 返回流中的第一个元素
        Optional<User> first = users.stream().findFirst();
        System.out.println(first);
        // Optional<T> findAny(); 随机返回流中的元素
        Optional<User> any = users.stream().findAny();
        System.out.println(any);

        //long count(); 返回流中元素的个数
        long count = users.stream().count();
        System.out.println(count);

        //  Optional<T> max(Comparator<? super T> comparator); 返回流中的最大值
        // 练习:返回工资最高的用户
        Optional<User>   max = users.stream().max(Comparator.comparingDouble(User::getSalary));
        System.out.println(max);

        //Optional<T> min(Comparator<? super T> comparator); 返回流中的最小值
        // 练习:返回用户中最少的工资
        // 使用 map 映射 工资,返回一个只有工资的流
        Optional<Double> min = users.stream().map(User::getSalary).min(Double::compare);
        System.out.println(min);

        // void forEach(Consumer<? super T> action); 迭代遍历
        users.stream().forEach(System.out::println);
    }

归约

image-20221103184203723

代码演示:

    // 归约
    @Test
    public void test2() {
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // T reduce(T identity, BinaryOperator<T> accumulator); 将流中的值反复结合起来得到一个新的值
        // 练习:计算1-10的和
        Integer reduce = integerList.stream().reduce(0, Integer::sum);
        System.out.println(reduce);

        List<User> users = User.getUserList();
        // Optional<T> reduce(BinaryOperator<T> accumulator); 将流中的值反复结合起来得到一个新的值,返回Optional<T>
        // 练习:计算所有用户的工资总和
        Optional<Double> reduce1 = users.stream().map(User::getSalary).reduce(Double::sum);
        System.out.println(reduce1);

    }

收集

image-20221103224946666

形参需要使用 Collectors 提供实例,调用以下方法

image-20221103224939085

Optional 类

  • 到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类 已经成为Java 8类库的一部分。

  • Optional 类(java.util.Optional) 是-一个 容器类,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用null表示-一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。

  • Optional类的Javadoc描述如下:这是一个可以为null的容器对象。如果值存在则 isPresent()方法会返回true,调用get()方法会返回该对象。

image-20221103191137885

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

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

相关文章

Electron 之通讯模块ipcMain 和 ipcRenderer

Electron一个使用HTML、CSS和JavaScript开发桌面应用程序的框架。Electron可以生成在Windows、macOS和Linux上运行的应用程序&#xff0c;借助Electron可以把我们的web端应用直接移植到桌面端而无需再次开发&#xff0c;这样我们可以使用同一套代码在不同平台上运行应用&#x…

数据收集面可视化

数据收集面可视化&#xff08;Data Collector Surface Visualization&#xff09;分析选项允许用户指定模型中的某一表面&#xff0c;在光线追迹的过程中收集光线数据&#xff0c;并显示或者输出该面的照度&#xff08;或相关的物理量&#xff09;。该分析选项允许计算&#xf…

电脑网页打不开提示错误err connection怎么办?

网页打不开显示err_connection_reset网络错误&#xff0c;怎么解决err_connection_reset网络错误&#xff1f;下面我们就来看看解决电脑err_connection_reset网络错误的方法&#xff0c;请看下文详细介绍。 方法一&#xff1a;组件注册 1、我们点下键盘的winR&#xff0c;输入…

2. 选择排序

2.1 内存的工作原理 需要将数据存储到内存时&#xff0c;你请求计算机提供存储空间&#xff0c;计算机给你一个存储地址。 需要存储多项数据时&#xff0c;有两种基本方式——数组和链表。 2.2 数组和链表 有时候&#xff0c;需要在内存中存储一系列元素。 使用数组意味着所…

ElasticSearch面试

Welcome to Elastic Docs | Elastic 1. ES的结构和底层实现 ES的整体结构? 一个 ES Index 在集群模式下&#xff0c;有多个 Node &#xff08;节点&#xff09;组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard &#xff08;分片&#xff09;&#xff0…

koa框架(二) mvc 模式及实现一个koa框架的web服务

mvc三层架构 mvc&#xff0c; 即 model 、controller、view&#xff1b;mvc模式将model、view、controller分离&#xff1b;使用mvc分层是系统更加灵活&#xff0c;扩展性更强。让程序更加直观、复用性更强、可维护性更强。 model 负责数据访问&#xff1b;controller 负责消息…

嵌入式设备文件系统构建——增加用户登录功能

1、修改inittab文件 #first:run the system script file ::sysinit:/etc/init.d/rcS# 进入命令行 #::askfirst:-/bin/sh#添加执行登录验证 ::sysinit:/bin/login::ctrlaltdel:-/sbin/reboot #umount all filesystem ::shutdown:/bin/umount -a -r #restart init process ::res…

2022-11-16 几种三角函数的图形

为了方便查看几个函数的关系图&#xff0c;记录一下几种三角函数的大致图像。 三角函数&#xff1a;tan⁡(x)\tan(x)tan(x)&#xff0c;cos⁡(x)\cos(x)cos(x)&#xff0c;sin⁡(x)\sin(x)sin(x)。 三角函数&#xff1a;tan⁡(x2)\tan(\dfrac{x}{2})tan(2x​)&#xff0c;cos…

盘点 三款高可用的机器学习模型 web页面化的工具(一)

笔者只是抛砖引玉&#xff0c;把三款看到的在本篇简单的介绍。 如果有其他更好的欢迎留言推荐&#xff0c;后续笔者会对这三款做一一的学习。 文章目录1 streamlit2 Gradio3 codepen1 streamlit 笔者之前写过该专题&#xff1a; python︱写markdown一样写网页&#xff0c;代码…

SpringCloud - 项目搭建

文章目录1.创建父工程项目2.父工程POM配置3.创建RestFul 服务器3.1 支付模块3.1.1 创建module3.1.2 改POM3.1.3 写YML3.1.4 主启动3.1.5 业务类3.2 订单模块3.2.1 创建module3.2.2 改POM3.2.3 写YML3.2.4 主启动3.2.5 业务类4.工程重构1.创建父工程项目 打开IDEA 创建一个Mave…

从零开始的深度学习之旅(1)

目录0.前言1.单层神经网络1.1 单层神经网络基础(线性回归算法)1.2 torch.nn.Linear实现单层回归神经网络的正向传播2.二分类神经网络&#xff1a;逻辑回归2.1 逻辑回归与门代码实现2.2 符号函数2.2.1 sign函数2.2.2 Relu函数2.2.3 tant函数3. 多分类神经网络&#xff1a;Softma…

Vue:实战快速上手

采用实战模式并结合ElementUI 组件库&#xff0c;将所需知识点应用到实际中&#xff0c;以最快速度掌握Vue的使用; 桌面化应用 ElementUI: https://element.eleme.cn/#/zh-CN/ 弹窗 LayUI 的 layer &#xff08;由于官网已下架&#xff0c;在此使用镜像): https://www.layui.s…

【网页设计】基于HTML在线图书商城购物项目设计与实现_(图书商城10页) bootstarp响应式

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 在线商城购物 | 水果商城 | 商城系统建设 | 多平台移动商城 | H5微商城购物商城项目 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&a…

[附源码]java毕业设计停车场信息管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

抢购软件使用方法(如何开发抢购软件)

如果做抢购软件的话需要好的协议以及算法&#xff0c;我用的这份协议目前非常稳定&#xff0c;所以今天给大家讲解下抢购软件的流程以及使用方法 01软件设置选项详解 一、无障碍服务 二、使用网路时间 软件第一行一般都是当前设备比XX慢了&#xff08;快了&#xff09;XXms&…

Vue3铺垫知识【ES6 模块化、Promise、async/await、EventLoop、宏任务和微任务、总结】

文章目录ES6 模块化1. 回顾&#xff1a;node.js 中如何实现模块化2. 前端模块化规范的分类3. 什么是 ES6 模块化规范4. 在 node.js 中体验 ES6 模块化5. ES6 模块化的基本语法5.15.1.1 默认导出5.1.2 默认导入5.1.3 默认导出的注意事项5.1.4 默认导入的注意事项5.25.2.1 按需导…

Python:Linux下安装Anaconda,可多人使用(内容几乎完整)

前言 前言属于与内容无关的写作意图。要看正文&#xff0c;请直接跳转至本文主要内容。 很久不见。最近手里有很多事&#xff0c;比如&#xff0c;体检、装机、加班。再加上我现在为了速记&#xff0c;会把东西记到跨平台的笔记软件“OneNote”&#xff08;大画板&#xff0c…

尚医通 (二十六) --------- 科室接口开发

目录一、上传科室接口1. 添加科室基础类2. 上传科室二、查询科室接口三、删除科室接口一、上传科室接口 1. 添加科室基础类 A、添加 model 说明&#xff1a;由于实体对象没有逻辑&#xff0c;我们已经统一导入 com.fancy.yygh.model.hosp.Department B、添加 repository 添…

多元正态分布

最广为使用的基于模型的聚类方法依赖于多元正态分布。多元正态分布是对p个变量正态分布的一种推广。该分布使用一组均值和协方差矩阵∑定义。协方差矩阵是变量间相关性的度量. 协方差矩阵∑由p个方差以及所有变量对的协方差σi,ji≠j&#xff09;构成。矩阵的行和列均用变量表…

闲活一:一步登天

标题不希望能被人搜到&#xff0c;因为目前没有任何技术含量&#xff0c;可行性也偏低&#xff0c;纯纯的预研阶段。 项目起步阶段是最无从下手的阶段&#xff0c;还是先明确大目标。我这个赛车要做什么&#xff0c;怎样去做。 做什么 我脑中蹦出的大方向是这样的 玩家体…