函数式接口、Stream流、方法引用、Junit、反射、注解
2021-10-14 14:36:12 25 举报
AI智能生成
函数式接口、Stream流、方法引用、Junit、反射、注解
作者其他创作
大纲/内容
函数式接口
函数式编程
常用函数式接口
都在java.util.function包下
都在java.util.function包下
Supplier接口
接口仅包含一个无参的方法: T get()
用来获取一个泛型参数指定类型的对象数据
由于这是一个函数式接口,这也就意味着对应的Lambda表达式
需要“对外提供”一个符合泛型类型的对象数据
用来获取一个泛型参数指定类型的对象数据
由于这是一个函数式接口,这也就意味着对应的Lambda表达式
需要“对外提供”一个符合泛型类型的对象数据
import java.util.function.Supplier;
public class Demo08Supplier {
private static String getString(Supplier<String> function) {
return function.get();
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
System.out.println(getString(() ‐> msgA + msgB));
}
}
public class Demo08Supplier {
private static String getString(Supplier<String> function) {
return function.get();
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
System.out.println(getString(() ‐> msgA + msgB));
}
}
Consumer接口
接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,
其数据类型由泛型决定。
其数据类型由泛型决定。
抽象方法:void accept(T t)
消费一个指定泛型的数据
消费一个指定泛型的数据
默认方法:andThen
如果一个方法的参数和返回值全都是Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,
然后再做一个操作,实现组合
如果一个方法的参数和返回值全都是Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,
然后再做一个操作,实现组合
Predicate接口
对某种类型的数据进行判断,从而得到一个boolean值结果
抽象方法:boolean test(T t)
默认方法:and
默认方法:or
默认方法:negate
Function接口
用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,
后者称为后置条件。
后者称为后置条件。
抽象方法:R apply(T t)
例如:将String 类型转换为Integer 类型
例如:将String 类型转换为Integer 类型
默认方法:andThen
Stream流
流式思想
当需要对多个元素进行操作(特别是多步操作)的时候,
考虑到性能及便利性,我们应该首先拼好一个“模型”步骤
方案,然后再按照方案去执行它。
考虑到性能及便利性,我们应该首先拼好一个“模型”步骤
方案,然后再按照方案去执行它。
Stream(流)是一个来自数据源的元素队列
1、元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
2、数据源 流的来源。 可以是集合,数组 等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
3、Pipelining: 中间操作都会返回流对象本身。(直到使用了终结方法如forEach、count) 这样多个操作可以串联成一个管道, 如同流式风格(fluent
style)(链式编程)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
4、内部迭代: 以前对集合遍历都是通过Iterator或者增强for的方式, 显式的在集合外部进行迭代, 这叫做外部迭
代。 Stream提供了内部迭代的方式,流可以直接调用遍历方法。
当使用一个流的时候,通常包括三个基本步骤:获取一个数据源(source)→ 数据转换→执行操作获取想要的结
果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以
像链条一样排列,变成一个管道。
1、元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
2、数据源 流的来源。 可以是集合,数组 等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
3、Pipelining: 中间操作都会返回流对象本身。(直到使用了终结方法如forEach、count) 这样多个操作可以串联成一个管道, 如同流式风格(fluent
style)(链式编程)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
4、内部迭代: 以前对集合遍历都是通过Iterator或者增强for的方式, 显式的在集合外部进行迭代, 这叫做外部迭
代。 Stream提供了内部迭代的方式,流可以直接调用遍历方法。
当使用一个流的时候,通常包括三个基本步骤:获取一个数据源(source)→ 数据转换→执行操作获取想要的结
果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以
像链条一样排列,变成一个管道。
获取流
根据Collection获取流
所有的Collection 集合都可以通过stream 默认方法获取流;
根据Map获取流
java.util.Map 接口不是Collection 的子接口,且其K-V数据结构不符合流元素的单一特征,所以获取对应的流
需要分key、value或entry等情况:都转换成Set集合
需要分key、value或entry等情况:都转换成Set集合
map.keySet().stream()获取Map集合中所有的键,存储到Set集合中,再通过stream()获取流
map.values().stream()获取Map集合中所有的值,存储到Set集合中
map.entrySet().stream()获取Map集合中所有的键值对对象,存储到Set集合中
根据数组获取流
Stream.of()
常用方法
逐一处理:forEach
该方法是一个终结方法,接收一个Consumer 接口函数,会将每一个流元素交给该函数进行处理
过滤:filter
该接口接收一个Predicate 函数式接口参数(可以是一个Lambda或方法引用)作为筛选条件。
映射:map
该接口需要一个Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流
统计个数:count
该方法是一个终结方法,返回一个long值代表元素个数(不再像旧集合那样是int值)
取用前几个:limit
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作
跳过前几个:skip
组合:concat
合并两个相同泛型的流
方法引用
Subtopic
Subtopic
Junit(单元测试)
测试分类
黑盒测试
不需要写代码,给输入值,看程序是否能够输出期望的值
白盒测试
需要写代码的。关注程序具体的执行流程
Junit使用:白盒测试
1. 定义一个测试类(测试用例)
* 建议:
* 测试类名:被测试的类名Test CalculatorTest
* 包名:xxx.xxx.xx.test cn.itcast.test
* 建议:
* 测试类名:被测试的类名Test CalculatorTest
* 包名:xxx.xxx.xx.test cn.itcast.test
2. 定义测试方法:可以独立运行
* 建议:
* 方法名:test测试的方法名 testAdd()
* 返回值:void
* 参数列表:空参
* 建议:
* 方法名:test测试的方法名 testAdd()
* 返回值:void
* 参数列表:空参
3. 给方法加@Test
4. 导入junit依赖环境
* 判定结果:
* 红色:失败
* 绿色:成功
* 一般我们会使用断言操作来处理结果
* Assert.assertEquals(期望的结果,运算的结果);
* 红色:失败
* 绿色:成功
* 一般我们会使用断言操作来处理结果
* Assert.assertEquals(期望的结果,运算的结果);
@Before:
修饰的方法会在测试方法之前被自动执行
修饰的方法会在测试方法之前被自动执行
@After:
修饰的方法会在测试方法执行之后自动被执行
修饰的方法会在测试方法执行之后自动被执行
反射:框架设计的灵魂
概念
* 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
* 反射:将类的各个组成部分封装为其他对象,这就是反射机制
* 好处:
1. 可以在程序运行过程中,操作这些对象。
2. 可以解耦,提高程序的可扩展性。
* 反射:将类的各个组成部分封装为其他对象,这就是反射机制
* 好处:
1. 可以在程序运行过程中,操作这些对象。
2. 可以解耦,提高程序的可扩展性。
Java代码在计算机经历的三阶段
1、获取Class对象
Class.forName("全类名"):将字节码文件加载进内存,返回Class对象(全类名含包名)
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
类名.class:通过类名的属性class获取
多用于参数的传递
多用于参数的传递
对象.getClass():getClass()方法在Object类中定义着
多用于对象的获取字节码的方式
多用于对象的获取字节码的方式
2、Class对象功能
获取成员变量
Field[] getFields() :获取所有public修饰的成员变量
Field getField(String name) 获取指定名称的 public修饰的成员变量
Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name) 获取指定名称的成员变量,不考虑修饰符
获取构造方法
Constructor<?>[] getConstructors()Field[] getFields() :获取所有public修饰的成员变量
Constructor<T> getConstructor(类<?>... parameterTypes) 获取指定名称的 public修饰的构造方法
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) 获取所有的构造方法,不考虑修饰符
Constructor<?>[] getDeclaredConstructors() 获取指定名称的构造方法,不考虑修饰符
例子
personClass.getConstructor(String.class , int.class)
personClass.getConstructor(String.class , int.class)
获取成员方法
Method[] getMethods() 获取所有public修饰的成员方法
Method getMethod(String name, 类<?>... parameterTypes) 获取指定名称public修饰的成员方法
Method[] getDeclaredMethods() 获取所有成员方法
Method getDeclaredMethod(String name, 类<?>... parameterTypes) 获取指定名称的成员方法
例子 类名.getMethod(方法名,数据类型.class)
获取全类名
String getName()
注解
0 条评论
下一页