Java8的Optional类的使用 和 Stream流式操作

news2025/7/19 6:04:37

Java知识点总结:想看的可以从这里进入

目录

      • 13.6、Optional类
      • 13.7、Stream
        • 13.7.1、Stream创建
        • 13.7.2、中间操作
          • 1、筛选
          • 2、切片
          • 3、映射
          • 4、排序
        • 13.7.3、终止操作
          • 1、遍历
          • 2、聚合
          • 3、匹配查找
          • 4、归约
          • 5、收集
            • 归集
            • 统计
            • 分组
            • 字符串拼接
            • 归约

13.6、Optional类

Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。使用它提供很多有用的方法,我们就可以不用显式进行空值检测。Optional的引入极大的解决了关于空指针异常方面的问题。

序号方法 & 描述
1static Optional of(T t): 创建一个 Optional 实例,t必须非空
2static Optional empty() :创建一个空的 Optional 实例
3static Optional ofNullable(T t):t可以为null,如果为null,返回空的 Optional,否则返回非空的 Optional实例
4void ifPresent(Consumer<? super T> consumer):如果有值,就执行Consumer接口的实现代码,并且该值会作为参数传给它。
5boolean isPresent():判断是否存在对象,存在则方法会返回true,否则返回 false。
6T get():如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
7T orElse(T other):如果有值则将其返回,否则返回指定的other对象。
8T orElseGet(Supplier<? extends T> other):如果有值则将其返回,否则返回由Supplier接口实现提供的对象
9T orElseThrow(Supplier<? extends X> exceptionSupplier):如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。
10boolean equals(Object obj):判断其他对象是否等于 Optional。
11Optional filter(Predicate<? super predicate):如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。
12 Optional flatMap(Function<? super T,Optional> mapper):如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
13int hashCode():返回存在值的哈希码,如果值不存在 返回 0。
14Optional map(Function<? super T,? extends U> mapper):如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。
15String toString():返回一个Optional的非空字符串,用来调试
Optional<String> s = Optional.of("张三");
System.out.println("s是否有值:"+s.isPresent());
System.out.println("如果存在返回否则返回不存在:"+s.orElse("不存在"));
System.out.println("获取值:"+s.get());

image-20230220182742874

13.7、Stream

Stream是JDK8版本中除了Lambda 表达式外最重要的改变。Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API 对流中的元素进行筛选、排序、聚合等操作。使用Stream API 对集合数据进行操作,类似于使用 SQL 执行的数据库查询。它保存的数据的类型为Optional类型

Stream 自己不会存储元素,它只是对集合数据进行操作,它在操作时不改变原有的数据,而是返回一个新的Stream,同事它的操作是有延迟的,只会在需要结果的时候才执行。

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

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

我们可以把Stream的操作看成一个管道,分为三个步骤,首先创建Stream,然后对管道中的数据进行中间操作,最后获得处理的结果。

  1. Stream的创建
  2. Stream 的中间操作
  3. Stream 的终止操作

13.7.1、Stream创建

  • 通过集合的方式:

    JDK8中 Collection 接口被扩展提供了2个方法:

    default Stream stream() :返回一个顺序流,由主线程按顺序对流执行操作

    default Stream parallelStream() :返回一个并行流,内部以多线程并行执行的方式对流进行操作

    List<String> list = new ArrayList<>();
    //创建顺序流
    Stream<String> listStream = list.stream();
    //创建并行流
    Stream<String> parallelStream = list.parallelStream();
    
  • 根据数组创建:java.util.Arrays.stream(T[] array)

    int[] nums = {1,2,3,4,5,6};
    IntStream arraysStream = Arrays.stream(nums);
    
  • 使用Stream的静态方法:

    • of():返回其元素为指定值的顺序有序流。

      image-20230220172041400
    • Stream.of().parallel():创建一个并行流

    • iterate():返回通过将函数f迭代应用到初始元素seed产生的无限顺序有序Stream ,产生由seed 、 f(seed) 、 f(f(seed))等组成的Stream 。

      image-20230220171919720
    • generate():返回无限顺序无序流,其中每个元素都由提供的Supplier生成。

      image-20230220171929034

13.7.2、中间操作

1、筛选
  1. 筛选:按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。

    • filter(Predicate p):通过Lambda表达式设置规则 , 从流中获取元素

      @Test
      public void main(){
          List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
          Stream<Integer> stream = list.stream();
          //筛选出集合中的偶数,并将结果放到一个新的Stream中
          Stream<Integer> stream1 = stream.filter(num -> num % 2 == 0);
          stream1.forEach(System.out::println);
      }
      

      image-20230220193530229

    • distinct():通过流所生成元素的 hashCode() 和 equals() 去除重复元素

      @Test
      public void main(){
          List<Integer> list = Arrays.asList(1, 2, 4, 4, 5, 6, 6, 8, 9);
          Stream<Integer> stream = list.stream();
          Stream<Integer> distinct = stream.distinct();
          distinct.forEach(System.out::print);
      }
      

      image-20230220200501446

2、切片
  1. limit(long maxSize):截断流,使其元素不超过给定数量

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> stream = list.stream();
        Stream<Integer> limit = stream.limit(5);
        limit.forEach(System.out::print);
    }
    

    image-20230220200647325

  2. skip(long n):从第n个位置往后截取,若流中元素不足 n 个,则返回一个空流(与 limit(n) 互补,limit(n)是截取第一个到n,而skip是从n到最后)

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> stream = list.stream();
        Stream<Integer> limit = stream.skip(5);
        limit.forEach(System.out::print);
    }
    

    image-20230220200927647

3、映射
  1. map(Function f):接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3,4,5,6,7,8,9);
    
        Stream<Integer> stream1 = list.stream();
        //将所有元素的值*2
        Stream<Integer> mapStream = stream1.map(num -> num * 2);
        mapStream.forEach(System.out::println);
    }
    
    image-20230220205401866
  2. flatMap(Function f):接收一个函数作为参数,将流中的每个值都换成另一个流返回,然后把所有流连接成一个流

    @Test
    public void main(){
        List<String> list1 = Arrays.asList("java","python","c++","c");
        //将每个元素从新生成一个stream,并添加test
        Stream<String> stringStream = list1.stream().flatMap(s -> {
            List<String> strings = Arrays.asList(s,"test");
            return strings.stream();
        });
        stringStream.forEach(System.out::println);
    }
    
    image-20230220210513283
  3. mapToDouble(ToDoubleFunction f):接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。

  4. mapToInt(ToIntFunction f):接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream

  5. mapToLong(ToLongFunction f):接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。

4、排序
  • sorted():产生一个新流,按自然顺序排序,按Comparable接口
  • sorted(Comparator com):产生一个新流,其中按比较器顺序排序,按Comparator自定义排序
@Test
public void main2(){
    List<Person> list = new ArrayList<>();
    list.add(new Person("张三","女",22,"学生"));
    list.add(new Person("李四","女",20,"学生"));
    list.add(new Person("王五","男",30,"工人"));
    list.add(new Person("赵六","男",10,"学生"));

    //按年龄升序排序
    Stream<Person> sorted = list.stream().sorted(Comparator.comparing(Person::getAge));
    sorted.forEach(System.out::println);
    //按年龄降序排序
    System.out.println("====按年龄降序排序====");
    Stream<Person> sorted1 = list.stream().sorted(Comparator.comparing(Person::getAge).reversed());
    sorted1.forEach(System.out::println);

    List<Integer> list1 = Arrays.asList(5,2,7,9,3);
    //自然排序
    Stream<Integer> sorted2 = list1.stream().sorted();
    sorted2.forEach(System.out::print);
    System.out.println();
    Stream<Integer> sorted3 = list1.stream().sorted(Comparator.reverseOrder());
    sorted3.forEach(System.out::print);

}
image-20230221152235288

13.7.3、终止操作

终止操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。流一旦进行了终止操作后,就不能再次使用了,否则会出现 java.lang.IllegalStateException: stream has already been operated upon or closed 这个异常。

1、遍历

Stream中的元素是以Optional类型存在的,支持类似集合的遍历。

  1. 使用forEach

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> stream = list.stream();
        //直接使用forEach
        stream.forEach(System.out::println);
    }
    
  2. 使用迭代器

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> stream = list.stream();
        Iterator<Integer> iterator = stream.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    
2、聚合

在Stream中有三个方法:

  1. count() :返回流中元素总数

  2. max(Comparator c):返回流中最大值

  3. min(Comparator c):返回流中最小值

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Stream<Integer> stream = list.stream();
        System.out.println("最小值:"+stream.min((o1, o2) -> o1-o2));
    
        //必须从新创建stream,因为max、min、count都是终止操作
        Stream<Integer> stream1 = list.stream();
        System.out.println("最大值:"+stream1.max((o1, o2) -> o1-o2));
    
        Stream<Integer> stream2 = list.stream();
        System.out.println("元素个数:"+stream2.count());
    }
    

    image-20230220195850649

3、匹配查找
  1. allMatch(Predicate p):检查是否匹配所有元素

  2. anyMatch**(**Predicate p) :检查是否至少匹配一个元素

  3. noneMatch(Predicate p):检查是否没有匹配所有元素

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    
        Stream<Integer> stream1 = list.stream();
        System.out.println("stream中的元素是否都>5:"+stream1.allMatch(x -> x > 5));
    
        Stream<Integer> stream2 = list.stream();
        System.out.println("stream中的元素是否至少有一个>5:"+stream2.anyMatch(x -> x > 5));
    
        Stream<Integer> stream3 = list.stream();
        System.out.println("stream中的元素是否都不>5:"+stream3.noneMatch(x -> x > 5));
    }
    

    image-20230220201709682

  4. findFirst():返回第一个元素

  5. findAny(): 返回当前流中的任意元素(适用于并行流),如果使用串行顺序流的话,它一般返回的就是第一个元素(建议多搞点数据,多运行几次,才能出现差别)

    @Test
    public void main(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    
        Stream<Integer> stream1 = list.stream();
        System.out.println("第一个元素是:"+stream1.findFirst());
    
        //创建并行流
        Stream<Integer> parallelStream1 = list.parallelStream();
        Stream<Integer> parallelStream2 = list.parallelStream();
        Stream<Integer> parallelStream3 = list.parallelStream();
        Stream<Integer> parallelStream4 = list.parallelStream();
        Stream<Integer> parallelStream5 = list.parallelStream();
        Stream<Integer> parallelStream6 = list.parallelStream();
        Stream<Integer> parallelStream7 = list.parallelStream();
        Stream<Integer> parallelStream8 = list.parallelStream();
        System.out.println("返回一个任意元素:"+parallelStream1.findAny());
        System.out.println("返回一个任意元素:"+parallelStream2.findAny());
        System.out.println("返回一个任意元素:"+parallelStream3.findAny());
        System.out.println("返回一个任意元素:"+parallelStream4.findAny());
        System.out.println("返回一个任意元素:"+parallelStream5.findAny());
        System.out.println("返回一个任意元素:"+parallelStream6.findAny());
        System.out.println("返回一个任意元素:"+parallelStream7.findAny());
        System.out.println("返回一个任意元素:"+parallelStream8.findAny());
    }
    

    image-20230220204755332

4、归约

归约,也称缩减,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

  1. reduce(T iden, BinaryOperator b):可以将流中元素反复结合起来,得到一个值。返回 T。
  2. reduce(BinaryOperator b):可以将流中元素反复结合起来得到一个值。返回 Optional

map 和 reduce 的连接通常称为 map-reduce 模式,因Google 用它来进行网络搜索而出名。

@Test
public void main(){
	List<Integer> list1 = Arrays.asList(1,2,3,4,5,6);
    //方式1:使用reduce(BinaryOperator b) ,返回值为Optional类
    //方式2:使用reduce(T iden, BinaryOperator b),返回值和T相关
    System.out.println("求和方式1:"+list1.stream().reduce(Integer::sum));
    System.out.println("求和方式2:"+list1.stream().reduce(0,Integer::sum));
    System.out.println("求乘积1:"+list1.stream().reduce((num1,num2) -> num1*num2));
    System.out.println("求乘积2:"+list1.stream().reduce(1,(num1,num2) -> num1*num2));

    System.out.println("求最大值1:"+list1.stream().reduce(Integer::max));
    System.out.println("求最大值2:"+list1.stream().reduce(0,Integer::max));

    System.out.println("求最小值:"+list1.stream().reduce(Integer::min));
    System.out.println("求最小值:"+list1.stream().reduce(10,Integer::min));
}
image-20230220212327591
5、收集

collect收集,是内容最繁多、功能最丰富的部分。它是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。collect主要依赖 java.util.stream.Collectors 类内置的静态方法。

collect(Collector c):将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

Collector 接口中方法的实现决定了如何对流执行收集的操作, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下

归集

归集:流是不存储数据,所以在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。

  • list.stream().collect(Collectors.toList()):把流中元素收集到List

    可简写为:list.stream().toList()

  • list.stream().collect(Collectors.toSet()):把流中元素收集到Set

  • list.stream().collect(Collectors.toCollection(ArrayList::new)):把流中元素收集到创建的集合

    @Test
    public void main(){
        List<Integer> list1 = Arrays.asList(1,2,3,4,5,6,6);
        //toList
        System.out.println("======toList方法======");
        List<Integer> toList = list1.stream().filter(num -> num % 2 == 0).toList();
        toList.forEach(System.out::print);
        System.out.println();
    
        //toSet
        System.out.println("======toSet方法======");
        Set<Integer> set = list1.stream().
                filter(num -> num%2==0).collect(Collectors.toSet());
        set.forEach(System.out::print);
        System.out.println();
    
        //toCollection
        System.out.println("======toCollection方法======");
        ArrayList<Integer> arrayList = list1.stream().
            filter(num -> num % 2 == 0).collect(Collectors.toCollection(ArrayList::new));
        arrayList.forEach(System.out::print);
    }
    
    image-20230221122656311
  • list.stream().collect(Collectors.toMap()):把流中元素收集到Map

    @Test
    public void main(){
        List<Person> list = new ArrayList<>();
        list.add(new Person("张三",20));
        list.add(new Person("李四",30));
    
        Map<String, Person> map = list.stream().
            collect(Collectors.toMap(Person::getName, p -> p));
        map.forEach((s, person) -> System.out.println(s+":"+person.toString()));
    }
    
    image-20230221140821010
统计
  • Long counting() :计算流中元素的个数(可直接用count)

  • 平均值

    • Double averagingInt():计算流中元素Integer属性的平均值(符合基本数据类型转换的规则)
    • Double averagingLong():计算流中元素Long属性的平均值(符合基本数据类型转换的规则)
    • Double averagingDouble():计算流中元素Double属性的平均值(符合基本数据类型转换的规则)
  • 最值

    • Optional maxBy():根据比较器选择最大值
    • Optional minBy():根据比较器选择最小值
  • 求和

    • Integer summingInt():对流中元素的整数属性求和
    • summingLong:对流中元素的Long属性求和
    • summingDouble对流中元素的doublt属性求和
  • 统计以上所有信息(个数、平均值、最值、和)

    • IntSummaryStatistics summarizingInt():收集流中Integer属性的统计值
    • summarizingLong
    • summarizingDouble
    @Test
    public void main(){
        List<Person> list = new ArrayList<>();
        list.add(new Person("张三",22));
        list.add(new Person("李四",20));
        list.add(new Person("王五",30));
        list.add(new Person("赵六",10));
    
        Long counting = list.stream().
            filter(person -> person.getAge() > 20).collect(Collectors.counting());
        System.out.println("年龄大于20的个数:"+counting);
    
        Double averagingInt = list.stream().collect(Collectors.averagingInt(Person::getAge));
        System.out.println("集合中年龄的平均值:"+averagingInt);
    
        Double averagingLong = list.stream()
            .collect(Collectors.averagingLong(Person::getAge));
        System.out.println("集合中年龄的平均值:"+averagingLong);
    
        Double averagingDouble = list.stream()
            .collect(Collectors.averagingDouble(Person::getAge));
        System.out.println("集合中年龄的平均值:"+averagingDouble);
    
        Optional<Integer> maxBy = list.stream().map(Person::getAge)
            .collect(Collectors.maxBy(Integer::compare));
        System.out.println("最大的年龄是:"+maxBy.get());
    
        Integer summingInt = list.stream().collect(Collectors.summingInt(Person::getAge));
        System.out.println("年龄的和是:"+summingInt);
    
        IntSummaryStatistics summarizingInt = list.stream()
            .collect(Collectors.summarizingInt(Person::getAge));
        System.out.println("根据年龄求以上信息:"+summarizingInt);
    }
    
    image-20230221134935773
分组

分组:将集合分为多个Map

  • Map<K, List> groupingBy():根据某属性值对流分组
  • Map<Boolean, List> partitioningBy():根据true或false进行分组
@Test
public void main(){
    List<Person> list = new ArrayList<>();
    list.add(new Person("张三","女",22,"学生"));
    list.add(new Person("李四","女",20,"学生"));
    list.add(new Person("王五","男",30,"工人"));
    list.add(new Person("赵六","男",10,"学生"));

    //按性别进行分组
    System.out.println("===按性别进行分组分组===");
    Map<String, List<Person>> mapByGender = list.stream().
        collect(Collectors.groupingBy(Person::getGender));
    mapByGender.forEach((s,person)-> System.out.println(s+":"+person.toString()));

    //按年龄是否>=20岁
    System.out.println("===按年龄是否>=20岁分组===");
    Map<Boolean, List<Person>> mapByAge = list.stream().
        collect(Collectors.partitioningBy(person -> person.getAge() >= 20));
    mapByAge.forEach((s,person)-> System.out.println(s+":"+person.toString()));

    //按年龄职业和性别分组
    System.out.println("===按职业和性别分组===");
    Map<String, Map<String, List<Person>>> mapByAgeAndGender = list.stream().
        collect(Collectors.groupingBy(Person::getGender, 
                                      Collectors.groupingBy(Person::getProfession)));
    mapByAgeAndGender.forEach((s,person)-> System.out.println(s+":"+person.toString()));
}

image-20230221143530143

字符串拼接

String joining(“连接符”) :连接流中每个字符串

@Test
public void main2(){
    List<Person> list = new ArrayList<>();
    list.add(new Person("张三","女",22,"学生"));
    list.add(new Person("李四","女",20,"学生"));
    list.add(new Person("王五","男",30,"工人"));
    list.add(new Person("赵六","男",10,"学生"));

    //不带连接符号
    String collect1 = list.stream().map(Person::getName).collect(Collectors.joining());
    System.out.println(collect1);
    //带连接符号
    String collect2 = list.stream().map(Person::getName).collect(Collectors.joining(","));
    System.out.println(collect2);

    Stream<String> stream = Stream.of("Java","Python","C++");
    String collect = stream.collect(Collectors.joining(","));
    System.out.println(collect);
}

image-20230221144219547

归约

reducing:从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值,相比于stream 本身的 reduce 方法,增加了对自定义归约的支持

image-20230221145918505

@Test
public void main2(){
    List<Person> list = new ArrayList<>();
    list.add(new Person("张三","女",22,"学生"));
    list.add(new Person("李四","女",20,"学生"));
    list.add(new Person("王五","男",30,"工人"));
    list.add(new Person("赵六","男",10,"学生"));

    //分别求出男女里最大的年龄是多少
    Map<String, Optional<Person>> collect = list.stream().collect(Collectors.groupingBy(Person::getGender, 	Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Person::getAge)))));
    
    collect.forEach((s,person)-> System.out.println(s+":"+person.toString()));
}

image-20230221150319339

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

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

相关文章

【已解决】异常断电文件损坏clickhouse启动不了:filesystem error Structure needs cleaning

问题 办公室有一台二手服务器&#xff0c;作为平时开发测试使用。由于机器没放在机房&#xff0c;会偶发断电异常断电后&#xff0c;文件系统是有出问题的可能的&#xff0c;尤其是一些不断在读写合并的文件春节后&#xff0c;发现clickhouse启动不了&#xff0c;使用systemct…

【Nginx】【一】Nginx简介

Nginx简介 背景介绍 Nginx&#xff08;“engine x”&#xff09;一个具有高性能的【HTTP】和【反向代理】的【WEB服务器】&#xff0c;同时也是一个【POP3/SMTP/IMAP代理服务器】&#xff0c;是由伊戈尔赛索耶夫(俄罗斯人)使用C语言编写的&#xff0c;Nginx的第一个版本是200…

nginx的平滑升级、反向代理负载均衡

文章目录一、负载均衡介绍二、nginx的平滑升级和版本回滚1.平滑升级2.版本回滚3.本实验纯代码过程三、反向代理负载均衡总结一、负载均衡介绍 四层负载均衡 所谓四层负载均衡是指OSI七层模型中的传输层, 那么传输层Nginx已经支持TCP/IP的控制, 所以只需要对客户端的请求进行TCP…

RPC编程:RPC概述和架构演变

RPC编程系列文章第一篇一&#xff1a;引言1&#xff1a;本系列文章的目标2&#xff1a;RPC的概念二&#xff1a;架构的演变过程1&#xff1a;单体架构1)&#xff1a;概念2)&#xff1a;特点3)&#xff1a;优缺点2&#xff1a;单体架构水平扩展1)&#xff1a;水平拓展的含义2)&a…

提到数字化,你想到哪些关键词

我们的生活中已经充满了数据&#xff0c;各种岗位例如运营、市场、营销上也都喜欢在职位要求加上一条利用数据、亦或是懂得数据分析。事实上&#xff0c;数据已经成为了构建现代社会的基本生产要素&#xff0c;并且因为不受自然环境的限制&#xff0c;已经成为了人们对未来社会…

【论文笔记】Manhattan-SDF==ZJU==CVPR‘2022 Oral

Neural 3D Scene Reconstruction with the Manhattan-world Assumption 本文工作&#xff1a;基于曼哈顿世界假设&#xff0c;重建室内场景三维模型。 1.1 曼哈顿世界假设 参考阅读文献&#xff1a;Structure-SLAM: Low-Drift Monocular SLAM in Indoor EnvironmentsIEEE IR…

ASEMI高压MOS管ASE20N65SE体积,ASE20N65SE大小

编辑-Z ASEMI高压MOS管ASE20N65SE参数&#xff1a; 型号&#xff1a;ASE20N65SE 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;650V 栅源电压&#xff08;VGS&#xff09;&#xff1a;30V 漏极电流&#xff08;ID&#xff09;&#xff1a;20A 功耗&#xff08;P…

Ardiuno-交通灯

LED交通灯实验实验器件&#xff1a;■ 红色LED灯&#xff1a;1 个■ 黄色LED灯&#xff1a;1 个■ 绿色LED灯&#xff1a;1 个■ 220欧电阻&#xff1a;3 个■ 面包板&#xff1a;1 个■ 多彩杜邦线&#xff1a;若干实验连线1.将3个发光二极管插入面包板&#xff0c;2.用杜邦线…

Docker----------day-mysql8主从复制

1.安装master 1.1拉取镜像 docker search mysql docker pull mysql mkdir -p /home/mysql8/data mkdir -p /home/mysql8/conf mkdir -p /home/mysql8/log1.2 2.启动交互式添加容器数据卷 #不添加容器数据卷 docker run -p 3307:3306 --name mysql_master -e MYSQL_ROOT_PASS…

xss基础

目录标题一、XSS的原理二、XSS漏洞分类1、反射型xss2、存储型XSS3、基于DOM的XSS三、XSS漏洞的危害及验证四、XSS漏洞的黑盒测试五、XSS漏洞的白盒测试一、XSS的原理 跨站脚本攻击XSS&#xff08;Cross Site Scripting&#xff09;&#xff0c;为了不和层叠样式表&#xff08;…

有序表之红黑树

文章目录1、五个条件2、调整策略2.1 插入调整的情况2.1.1 情况一&#xff1a;插入节点是红色&#xff0c;其父节点也是红色2.1.2 情况二2.1.2 代码实现2.2 删除调整的情况2.2.1 情况一&#xff1a;双重黑节点的兄弟节点也是黑色&#xff0c;且其兄弟的两个孩子也是黑色2.2.2 情…

100亿级订单怎么调度,来一个大厂的极品方案

背景 超时处理&#xff0c;是一个很有技术难度的问题。 所以很多的小伙伴&#xff0c;在写简历的时候&#xff0c;喜欢把这个技术难题写在简历里边&#xff0c; 体现自己高超的技术水平。 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;尼恩经常指导大家 优化简历。 最…

教你学git

前言 git是一种用于多人合作写项目。详细说明如下 文章目录前言什么是版本控制&#xff1f;什么是 Git&#xff1f;它就属于人工版本控制器版本控制工具常见版本控制工具怎么工作的&#xff1f;git 文件生命周期状态区域安装配置-- global检查配置创建仓库工作流与基本操作查看…

高精密数字源表的发展史

在半导体、汽车、医疗等高端制造行业&#xff0c;源表通常被用于半导体材料或精密器件的电性能特性测试和生产测试应用&#xff0c;以及中低电平测试和实验室研究使用。源表采用四象限工作模式&#xff0c;可以在提供精密电压、电流源的同时&#xff0c;又能够作为电压、电流、…

浅谈Java线程池中的ThreadPoolExecutor工具类

目录 ThreadPoolExecutor的构造函数 关于线程池的一些补充 线程池运行原理分析 概念原理解释 整个流程图如下&#xff1a; 一点补充 创建线程池主要有两种方式&#xff1a; 通过Executor工厂类创建&#xff0c;创建方式比较简单&#xff0c;但是定制能力有限通过ThreadPoo…

Git ---- 概述

Git ---- 概述1. 何为版本控制2. 为什么需要版本控制3. 版本控制的工具集中式版本控制工具分布式版本控制工具4. Git 简史5. Git 工作机制6. Git 和代码托管中心Git 是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目。 Git 易于学…

深入浅出C++ ——继承

文章目录一、继承的相关概念1. 继承的概念2. 继承格式3. 继承方式4. 访问限定符5. 继承基类成员访问方式的变化二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、菱形继承及菱形虚拟继承1. 单继承2. 多继承3. 菱形…

【比赛合集】9场可报名的「创新应用」、「程序设计」大奖赛,任君挑选!

CompHub 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号同时会推送最新的比赛消息&#xff0c;欢迎关注&#xff01;更多比赛信息见 CompHub主页 或 点击文末阅读原文以下信息仅供参考&#xff0c;以比赛官网为准目录创新应用赛&…

基于Java+SpringBoot+Vue+Uniapp前后端分离健身预约系统设计与实现

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战✌ 博主作品&#xff1a;《微服务实战》专栏是本人的实战经验总结&#xff0c;《Spring家族及…

linux集群技术(二)--keepalived(高可用集群)(一)

高可用集群简介keepalived简介 1.高可用集群简介 1.1什么是高可用集群 高可用集群&#xff08;High Availability Cluster&#xff0c;简称HA Cluster&#xff09;&#xff0c;是指以减少服务中断时间为目的的服务器集群技术。它通过保护用户的业务程序对外不间断提供的服务&am…