【工作记录】Lambda表达式学习总结

news/2025/1/12 23:03:25/

Lambda是什么

Lambda表达式是一种匿名函数,它可以在代码中被声明和传递,而不需要命名。Lambda表达式通常用于编写简洁的、非常具有可读性的代码,尤其是在函数式编程语言中。

一个Lambda表达式由参数列表、箭头符号和函数体组成。例如,(x, y) -> x + y 是一个接受两个参数的Lambda表达式,将它们相加并返回结果。

Lambda表达式可以被传递给其他函数作为参数,也可以被存储在变量中,以便之后使用。Lambda表达式通常与Java 8中的Stream API等函数式编程工具一起使用,以实现更具表现力的代码。

什么是函数式接口

函数式接口是指只有一个抽象方法的接口,它们通常被用作 Lambda 表达式的类型。Java 8 引入了函数式接口概念,并添加了 @FunctionalInterface 注解来标记一个接口为函数式接口,以便编译器检查该接口是否符合函数式接口的定义。函数式接口可以被用于创建 Lambda 表达式和方法引用等功能,并且在 Java 标准库中也提供了许多常用的函数式接口,如 ConsumerSupplierFunction 等。

Java8标准库中的函数式接口

在JDK中,常见的函数式接口分为四类,分别是

  • 消费型函数式接口 Consumer 常用于遍历 void accpet(T t)
  • 供给型函数式接口 Supplier 用于产生数据 T get()
  • 断言型函数式接口 Predicate 用于判断 boolean test(T t)
  • 函数型函数式接口 Function<T,R> 用于逻辑处理 R apply(T t)

Consumer接口

Consumer是一个消费型的接口,接收一个输入参数并且无返回的操作,即拿到某个数据时,进行消费,对该数据进行后续的一些操作。

@FunctionalInterface
public interface Consumer<T> {/*** Performs this operation on the given argument.** @param t the input argument*/void accept(T t);/*** Returns a composed {@code Consumer} that performs, in sequence, this* operation followed by the {@code after} operation. If performing either* operation throws an exception, it is relayed to the caller of the* composed operation.  If performing this operation throws an exception,* the {@code after} operation will not be performed.** @param after the operation to perform after this operation* @return a composed {@code Consumer} that performs in sequence this* operation followed by the {@code after} operation* @throws NullPointerException if {@code after} is null*/default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}}
  • java.util.function.Consumer<T>接口是消费一个数据,其数据类型由泛型决定。Consumer接口中包含抽象方法void accept(T t),意为消费一个指定泛型的数据。
  • Consumer接口是一个消费型接口,泛型执行什么类型,就可以使用accept方法消费什么类型的数据,至于具体怎么消费(使用),需要自定义实现等。

举个例子: 将手机号脱敏输出

public static void reverseStr(String sourceStr, Consumer<String> consumer) {consumer.accept(sourceStr);
}public static void main(String[] args) {reverseStr("18828989098", str -> {String regx = "(\\d{3})\\d{4}(\\d{4})";str = str.replaceAll(regx, "$1****$2");System.out.println("转换后的结果:" + str);});
}

Supplier接口

Supplier是一个供给型接口,其中的get方法用于返回一个值;Supplier也有许多的变种,例如IntSupplierLongSupplierBooleanSupplier等。

@FunctionalInterface
public interface Supplier<T> {/*** Gets a result.** @return a result*/T get();
}
  • java.util.function.Supplier<T>接口仅包含一个无参的方法:T get()。用来获取一个泛型参数指定类型的对象数据。
  • Supplier<T>接口被称之为生产型接口,指定接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据。

适用场景: 新建对象

举个例子: 新建一个用户对象

public static void main(String[] args) {Supplier<User> supplier = User::new;System.out.println(supplier.get().getUsername());
}@Data
public class User {private String id = "123456";private String username = "泽济天下";
}

Predicate接口

Predicate接口对某种数据类型的数据进行判断,返回一个布尔值。

@FunctionalInterface
public interface Predicate<T> {/*** Evaluates this predicate on the given argument.** @param t the input argument* @return {@code true} if the input argument matches the predicate,* otherwise {@code false}*/boolean test(T t);/*** Returns a composed predicate that represents a short-circuiting logical* AND of this predicate and another.  When evaluating the composed* predicate, if this predicate is {@code false}, then the {@code other}* predicate is not evaluated.** <p>Any exceptions thrown during evaluation of either predicate are relayed* to the caller; if evaluation of this predicate throws an exception, the* {@code other} predicate will not be evaluated.** @param other a predicate that will be logically-ANDed with this*              predicate* @return a composed predicate that represents the short-circuiting logical* AND of this predicate and the {@code other} predicate* @throws NullPointerException if other is null*/default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) && other.test(t);}/*** Returns a predicate that represents the logical negation of this* predicate.** @return a predicate that represents the logical negation of this* predicate*/default Predicate<T> negate() {return (t) -> !test(t);}/*** Returns a composed predicate that represents a short-circuiting logical* OR of this predicate and another.  When evaluating the composed* predicate, if this predicate is {@code true}, then the {@code other}* predicate is not evaluated.** <p>Any exceptions thrown during evaluation of either predicate are relayed* to the caller; if evaluation of this predicate throws an exception, the* {@code other} predicate will not be evaluated.** @param other a predicate that will be logically-ORed with this*              predicate* @return a composed predicate that represents the short-circuiting logical* OR of this predicate and the {@code other} predicate* @throws NullPointerException if other is null*/default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t);}/*** Returns a predicate that tests if two arguments are equal according* to {@link Objects#equals(Object, Object)}.** @param <T> the type of arguments to the predicate* @param targetRef the object reference with which to compare for equality,*               which may be {@code null}* @return a predicate that tests if two arguments are equal according* to {@link Objects#equals(Object, Object)}*/static <T> Predicate<T> isEqual(Object targetRef) {return (null == targetRef)? Objects::isNull: object -> targetRef.equals(object);}
}
  • java.util.function.Predicate接口 作用:对某种数据类型的数据进行判断,结果返回一个boolean值。
  • Predicate接口中包含一个抽象方法:boolean test(T t):用来对指定数据类型数据进行判断的方法;结果符合条件返回true,否则返回false。

举个例子: 判断字符串长度是否为11

public static void main(String[] args) {Predicate<String> predicate = str -> str.length() == 11;boolean test = predicate.test("123");System.out.println("test = " + test);  
}

Function接口

Function是一个功能型的接口,用于将一种类型的数据转化为另外一种类型的数据。比如我们常见的list转map就用的是Fuction接口。

@FunctionalInterface
public interface Function<T, R> {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t);/*** Returns a composed function that first applies the {@code before}* function to its input, and then applies this function to the result.* If evaluation of either function throws an exception, it is relayed to* the caller of the composed function.** @param <V> the type of input to the {@code before} function, and to the*           composed function* @param before the function to apply before this function is applied* @return a composed function that first applies the {@code before}* function and then applies this function* @throws NullPointerException if before is null** @see #andThen(Function)*/default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {Objects.requireNonNull(before);return (V v) -> apply(before.apply(v));}/*** Returns a composed function that first applies this function to* its input, and then applies the {@code after} function to the result.* If evaluation of either function throws an exception, it is relayed to* the caller of the composed function.** @param <V> the type of output of the {@code after} function, and of the*           composed function* @param after the function to apply after this function is applied* @return a composed function that first applies this function and then* applies the {@code after} function* @throws NullPointerException if after is null** @see #compose(Function)*/default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}/*** Returns a function that always returns its input argument.** @param <T> the type of the input and output objects to the function* @return a function that always returns its input argument*/static <T> Function<T, T> identity() {return t -> t;}
}

举个例子: 手机号脱敏后返回

public static void main(String[] args) {Function<String, String> func = str -> {if(str.length() == 11) {String regx = "(\\d{3})\\d{4}(\\d{4})";return str.replaceAll(regx, "$1****$2");};return "不符合规则";};String apply = func.apply("1882898090222");System.out.println("转换后的数据 = " + apply);
}

除了上面提到的四个函数式接口外,标准库还提供了一系列Bi开头的同类接口,用于接受或者返回多个参数。

BiConsumer接口

BiConsumer<T, U>接口是一个函数接口,该接口声明了accept方法,并无返回值,该函数接口主要用来声明一些预期操作。
其中还有一个andThen方法,该方法接受一个BiConsumer,返回一个组合的BiConsumer,并且按照顺序执行操作。如果执行任一操作抛出异常,则将其传递给组合操作的调用者。 如果执行此操作抛出异常,将不执行后操作(after)。

public class MainTest {public static void main(String[] args) {System.out.println("------BiPredicate------");BiPredicate<String,String> biPredicate = (x,y)-> x.equals(y);BiPredicate<String,String> biPredicate1 = (x,y)-> (x+"2").equals(y);System.out.println("False>>>>>:"+biPredicate.test("a","b"));System.out.println("True>>>>>:"+biPredicate.test("a","a"));//biPredicate和biPredicate1是否同时满足System.out.println("and >>>>>:"+biPredicate.and(biPredicate1).test("xxx","xxx2"));//negate表示非运算,类似"!"System.out.println("negate >>>>>:"+biPredicate.negate().test("a","a"));System.out.println("negate >>>>>:"+biPredicate.negate().test("a","c"));//or或者System.out.println("or >>>>>:"+biPredicate.or(biPredicate1).test("xxx","xxx2"));System.out.println("or >>>>>:"+biPredicate.or(biPredicate1).test("xxx","xx"));System.out.println("------BiPredicate------");}
}

输出内容为:

------BiConsumer------
JACK--------------JAVA8
biConsumer2--------------JAVA8
biConsumer2>>>>>>>>JAVA8
------BiConsumer------

BiFunction接口

BiFunction<T, U, R>接口是一个函数接口,声明了apply方法,有返回值R.其中包含一个default的andThen(Function<? super R, ? extends V> after),接受一个Function方法,返回一个结果。

public static void main(String[] args) {System.out.println("------BiFunction------");BiFunction<Integer,Integer,Integer>    = (x, y)-> {return  x+y;};int result =  biFunction.apply(1,2);System.out.println("result:"+result);Function<Integer,Integer> function = (x)->{return (x*5);};System.out.println("andThen:"+biFunction.andThen(function).apply(8,9));System.out.println("------BiFunction------");
}

输出结果:

------BiFunction------
result:3
andThen:85
------BiFunction------

上面的result:3是很容易理解的,就是1+2,也就是执行了biFunction,下面输出的85,则是先执行了biFunction.apply(8,9),然后在执行的自定义的function函数。最后计算公式也就是(8+9*5=85。

BinaryOperator接口

代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果。他继承了BiFunction,因此可以使用BiFunction中的方法。

public class MainTest {public static void main(String[] args) {System.out.println("------BinaryOperator------");BinaryOperator<Integer> binaryOperator = (x,y)->x*y;System.out.println("BinaryOperator:"+binaryOperator.apply(3,8));Function<Integer,Integer> function1 = (x)->x*8;System.out.println("BinaryOperator andThen:" + binaryOperator.andThen(function1).apply(8,10));BinaryOperator<Integer> bi = BinaryOperator.maxBy(Comparator.naturalOrder());System.out.println("BinaryOperator maxBy:" + (bi.apply(100,99)));System.out.println("------BinaryOperator------");}
}

输出结果:

------BinaryOperator------
BinaryOperator:24
BinaryOperator andThen:640
BinaryOperator maxBy:100
------BinaryOperator------

BiPredicate接口

代表了一个两个参数的boolean值方法。该接口是一个逻辑运算的函数接口;里面包含了比较方法boolean test(T t, U u),逻辑与方法and(BiPredicate<? super T, ? super U> other),逻辑非方法negate(),以及逻辑或方法or(BiPredicate<? super T, ? super U> other)。
test(T t, U u) :判断参数是否满足条件。
and(BiPredicate<? super T, ? super U> other):同时满足。
negate():非运算,类似“!”.
or(BiPredicate<? super T, ? super U> other):或运算。

public class MainTest {public static void main(String[] args) {System.out.println("------BiPredicate------");BiPredicate<String,String> biPredicate = (x,y)-> x.equals(y);BiPredicate<String,String> biPredicate1 = (x,y)-> (x+"2").equals(y);System.out.println("False>>>>>:"+biPredicate.test("a","b"));System.out.println("True>>>>>:"+biPredicate.test("a","a"));//biPredicate和biPredicate1是否同时满足System.out.println("and >>>>>:"+biPredicate.and(biPredicate1).test("xxx","xxx2"));//negate表示非运算,类似"!"System.out.println("negate >>>>>:"+biPredicate.negate().test("a","a"));System.out.println("negate >>>>>:"+biPredicate.negate().test("a","c"));//or或者System.out.println("or >>>>>:"+biPredicate.or(biPredicate1).test("xxx","xxx2"));System.out.println("or >>>>>:"+biPredicate.or(biPredicate1).test("xxx","xx"));System.out.println("------BiPredicate------");}
}

输出结果:

------BiPredicate------
False>>>>>:false
True>>>>>:true
and >>>>>:false
negate >>>>>:false
negate >>>>>:true
or >>>>>:true
or >>>>>:false
------BiPredicate------

BooleanSupplier接口

代表了boolean值结果的提供方,用于接收Lambda表达式所返回的boolean值结果。

public class MainTest {public static void main(String[] args) {System.out.println("------BooleanSupplier------");BooleanSupplier booleanSupplier = ()->true;System.out.println(" booleanSupplier :" + booleanSupplier.getAsBoolean());int x=2;int y=3;BooleanSupplier booleanSupplier1 = ()->x>y;System.out.println(" booleanSupplier1 :" + booleanSupplier1.getAsBoolean());System.out.println("------BooleanSupplier------");}
}  

输出结果:

------BooleanSupplier------
booleanSupplier :true
booleanSupplier1 :false
------BooleanSupplier------

Java8中的Stream流以及流式编程

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

对于Java语言,我们最常用的面向对象编程都属于命令式编程。在Java8的时候,引入了函数式编程。

Java8前,对集合进行处理、排序、对集合多次操作、对集合进行处理后,返回一些符合要求的特定的集合等,都比较麻烦。我们通常需要对集合进行遍历处理,写许多冗余代码。所以Java8引入了基于流式编程的Stream对集合进行一系列的操作。

Stream不是集合元素,也不是数据结构,它相当于一个高级版本的Iterator,不可以重复遍历里面的数据,像水一样,流过了就一去不复返。它和普通的Iterator不同的是,它可以并行遍历,普通的Iterator只能是串行,在一个线程中执行。

Stream它并不是一个容器,它只是对容器的功能进行了增强,添加了很多便利的操作,例如查找、过滤、分组、排序等一系列的操作。并且有串行、并行两种执行模式,并行模式充分的利用了多核处理器的优势,使用fork/join框架进行了任务拆分,同时提高了执行速度。简而言之,Stream就是提供了一种高效且易于使用的处理数据的方式。

串行流操作在一个线程中依次完成;并行流在多个线程中完成。

常见场景

创建Stream

创建Stream主要有以下几种方法;

  • 通过 java.util.Collection.stream() 方法用集合创建流
ArrayList<String> arrayList = CollUtil.toList("aaa", "bbb", "ccc");
Stream<String> stream = arrayList.stream(); // 创建一个顺序流
Stream<String> stringStream = arrayList.parallelStream(); // 创建一个并行流
  • 使用java.util.Arrays.stream(T[] array)方法用数组创建流
int[] array = {1,2,3,7,9,13};
IntStream stream = Arrays.stream(array);
  • 使用Stream的静态方法创建:of()、iterate()、generate()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

collect(Collectors.toList())

collect(Collectors.toList())是将流转换为List

List<Student> studentList = Stream.of(new Student("20220210", "贾玲", 12, "陕西省西安市"),new Student("20220211", "李四", 13, "江苏省南京市"),new Student("20220212", "李红", 12, "河北省石家庄市")).collect(Collectors.toList());
System.out.println("studentList = " + studentList);

结果:

studentList = [Student(id=20220210, name=贾玲, age=12, address=江苏省陕西省西安市市), Student(id=20220211, name=李四, age=13, address=江苏省南京市), Student(id=20220212, name=李红, age=12, address=河北省石家庄市)]

除此之外,还有.collect(Collectors.toSet()).collect(Collectors.toMap(Student::getId, Function.identity()))等。

Set<Student> studentSet = Stream.of(new Student("20220210", "贾玲", 12, "陕西省西安市"),new Student("20220211", "李四", 13, "江苏省南京市"),new Student("20220212", "李红", 12, "河北省石家庄市")).collect(Collectors.toSet());
System.out.println("studentSet = " + studentSet);

结果:

studentSet = [Student(id=20220210, name=贾玲, age=12, address=陕西省西安市), Student(id=20220211, name=李四, age=13, address=江苏省南京市), Student(id=20220212, name=李红, age=12, address=河北省石家庄市)]

Map<String, Student> studentMap = Stream.of(new Student("20220210", "贾玲", 12, "陕西省西安市"),new Student("20220211", "李四", 13, "江苏省南京市"),new Student("20220212", "李红", 12, "河北省石家庄市")).collect(Collectors.toMap(Student::getId, Function.identity()));
System.out.println("studentMap = " + studentMap);

结果:

studentMap = {20220210=Student(id=20220210, name=贾玲, age=12, address=陕西省西安市), 20220211=Student(id=20220211, name=李四, age=13, address=江苏省南京市), 20220212=Student(id=20220212, name=贾玲, age=12, address=河北省石家庄市)}

以下是使用的测试实体类Student:

Student类

@Data
@ToString
@AllArgsConstructor
public class Student implements Serializable {private String id;private String name;private int age;private String address;
}
List<Student> studentArrayList = new ArrayList<>();
studentArrayList.add(new Student("20220210", "贾玲", 12, "陕西省西安市"));
studentArrayList.add(new Student("20220211", "李四", 13, "江苏省南京市"));
studentArrayList.add(new Student("20220212", "李红", 12, "河北省石家庄市"));

筛选filter

示例:筛选学生年龄小于13岁的学生数据

List<Student> studentList = studentArrayList.stream().filter(item -> item.getAge() < 13).collect(Collectors.toList());
System.out.println("studentList = " + studentList);

输出:

studentList = [Student(id=20220210, name=贾玲, age=12, address=江苏省苏州市), Student(id=20220212, name=李红, age=12, address=安徽省合肥市)]

转换map

示例:输出所有学生的姓名信息

List<String> nameList = studentArrayList.stream().map(item->item.getName()).collect(Collectors.toList());
System.out.println("nameList = " + nameList);

输出:

nameList = [贾玲, 李四, 李红]

最大值max、最小值min

示例:输出所有学生信息中年龄最大以及年龄最小的学生信息

Optional<Student> ageMax = studentArrayList.stream().max(Comparator.comparing(item -> item.getAge()));
// 使用isPresent方法判断是否有值,否则遇到null是直接get()操作引发异常
if (ageMax.isPresent()) {Student student = ageMax.get();System.out.println("student = " + student);
}
Optional<Student> ageMin = studentArrayList.stream().min(Comparator.comparing(item -> item.getAge()));
// 使用isPresent方法判断是否有值,否则遇到null是直接get()操作引发异常
if (ageMax.isPresent()) {Student student = ageMin.get();System.out.println("student = " + student);
}

输出:

student = Student(id=20220211, name=李四, age=13, address=江苏省南京市) student = Student(id=20220210, name=贾玲, age=12, address=江苏省苏州市)

统计count

示例:统计所有学生中年龄小于13岁的人数

long count = studentArrayList.stream().filter(item -> item.getAge() < 13).count();
System.out.println("count = " + count);

输出:

count = 2

接合joining

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

示例:将所有学生的姓名输出,并用,作分隔符

String collect = studentArrayList.stream().map(item -> item.getName()).collect(Collectors.joining(","));
System.out.println("collect = " + collect);

输出:

collect = 贾玲,李四,李红

分组groupingBy

示例:将所有学生信息按性别分组

Map<Integer, List<Student>> collect = studentArrayList.stream().collect(Collectors.groupingBy(Student::getAge));
System.out.println("collect = " + collect);

输出:

collect = {12=[Student(id=20220210, name=贾玲, age=12, address=江苏省苏州市), Student(id=20220212, name=李红, age=12, address=安徽省合肥市)], 13=[Student(id=20220211, name=李四, age=13, address=江苏省南京市)]}

流的合并concat、去重distinct、限制limit、跳过skip

示例:将两个stream进行合并,并作去重处理

Stream<String> stream1 = CollUtil.toList("aa", "bb", "cc", "dd").stream();
Stream<String> stream2 = CollUtil.toList("bb", "cc", "ee", "ff").stream();
List<String> stringList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
System.out.println("stringList = " + stringList);

输出:

stringList = [aa, bb, cc, dd, ee, ff]

示例:从1开始,输出前10个奇数值

List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
System.out.println("collect = " + collect);

输出:

collect = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

示例:从1开始,跳过前2个元素,输出前6个奇数元素

List<Integer> collect = Stream.iterate(1, x -> x + 2).skip(2).limit(6).collect(Collectors.toList());
System.out.println("collect = " + collect);

输出:

collect = [5, 7, 9, 11, 13, 15]

总结

本文主要总结了Java8提供的函数式接口以及流式编程常见场景。

针对以上内容有任何疑问或者建议欢迎留言~

创作不易,欢迎一键三连~~~


http://www.ppmy.cn/news/87306.html

相关文章

支付宝支付示例

引入alipay-sdk-java依赖 创建AlipayConfig类&#xff0c;包含支付宝相关配置信息 public class AlipayConfig {// 商户appidpublic static String APPID "";// 私钥public static String RSA_PRIVATE_KEY "";// 支付宝公钥public static String ALIPA…

章节1:Burp Suite基本介绍

章节1&#xff1a;Burp Suite基本介绍 Burp [bɜ:p] Suite [swiːt] 01 Burp Suite基本介绍 官网介绍 https://portswigger.net/ 主要产品 Burp Suite培训和认证&#xff08;Academy&#xff09;研究院&#xff08;Research&#xff09;日报&#xff08;Daily&#xff09;…

PHP+vue高校教学考研资料分享系统

运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp5 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat/phpmyadmin用户首次登录系统需要注册一个用户&#xff0c;用户在登陆平…

AIGC功能在线制作思维导图?

ProcessOn思维导图软件是一款功能强大的在线制作思维导图的工具&#xff0c;它提供了丰富的模板和图标&#xff0c;可以帮助用户快速制作出高质量的思维导图。其中&#xff0c;AIGC(人工智能图形识别)功能是 ProcessOn软件中的一大特色&#xff0c;它可以帮助用户更加高效地制…

【三维激光扫描】实验05:点云数据预处理操作

SiScan软件可以对三维激光扫描的点云数据进行一些列的预处理操作,如:粗差剔除、点云抽稀、点云分割、调整水平面、删除分割面等等。 粗差剔除剔除粗差点抽稀抽稀数据点云分割根据点云的三维特征进行分组调整水平面根据三个点来调整水平面分割面水平纠正根据分割面进行水平纠正…

存放页的大池子——InnoDB表空间

在上一章节中&#xff0c;我们知道了提到了表空间&#xff0c;表空间里面没有直接存放表&#xff0c;有的是许多许多的页&#xff0c;我们也说了表空间的分类&#xff0c;有系统表空间&#xff0c;独立表空间&#xff0c;其他表空间。 每个新建的表都会在对应的数据库目录里面…

设计模式期末程序题(只是一个简单整理)

1.下图是某系统的数据部分的类图。因为该层次结构中的操作需要经常变化&#xff0c;所以需要用访问者模式对其进行重构&#xff0c;请按以下要求完成题目&#xff1a; &#xff08;1&#xff09;绘制重构后系统完整类图。&#xff08;4分&#xff09; &#xff08;2&#xff09…

小型双轮差速底盘实现红外避障功能

1. 功能说明 在R023e机器人车体上安装1个近红外传感器&#xff0c;实现机器人小车避障功能。 2. 电子硬件 在这个示例中&#xff0c;我们采用了以下硬件&#xff0c;请大家参考&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09; 扩展板 Bigfish2.1扩展板…