void shutdownOutput(): 关闭输出流, 发送结束标Day - 12 - 2018年11月28日函数式接口
1. 函数式接口概念
自定义函数式接口:
接口中有且只有一个抽象方法
自定义函数式接口:
接口中有且只有一个抽象方法
2. 函数式接口的使用
函数式接口的使用:
作为方法的参数类型, 传递Lambda表达式, 代替匿名内部类方式
3. 常用函数式接口
Supplier<T>: 生产型函数式接口 获取值
Consumer<T>: 消费型函数式接口 使用值
Predicate<T>: 条件判断型函数式接口 判断值
Function<T, R>: 转换型函数式接口 转换值
4. Supplier生产型函数式接口
// 抽象方法
T get(): 用于获取一个对象或值.
至于获取什么值, 怎么获取, 需要我们根据应用场景编写Lambda来实现
5. Consumer消费型函数式接口
StringBuilder reverse(): 将StringBuilder内部保存的内容反转
String toString(): 转换为String
new StringBuilder("abc").reverse().toString(); -> "cba" "abc" -> "cba"
// 抽象方法
void accept(T t): 用于消费(使用)一个对象或值. 至于怎么消费, 要我们根据应用场景编写Lambda实现
7. Consumer消费型函数式接口: 默认方法andThen()
default Consumer<T> andThen(Consumer<? super T> after): 拼接两个Consumer接口的Lambda对 象实现连续操作. 谁写前面, 谁先消费
8. Predicate条件判断函数式接口
// 抽象方法
boolean test(T t): 判断参数传递的对象. 至于怎么判断, 判断什么, 需要我们编写Lambda表达式实现
// 默认方法 (用于连接多个判断条件)
default Predicate<T> and(Predicate<? super T> other): 与 &&
default Predicate<T> or(Predicate<? super T> other): 或 ||
default Predicate<T> negate(): 非, 取相反结果
boolean b = 判断方式1.or(判断方式2).and(判断方式3).negate().test("abc")
9. Function转换型函数式接口
T是 输入(input)的类型
R是 返回结果(result)的类型
// 抽象方法
R apply(T t): 将T转换为R. 至于T和R是什么类型, 以及如何转换, 需要传递Lambda表达式实现Day - 13 - 2018年11月30日 Stream 方法引用
1. Stream流
使用Stream流的3个步骤:
1. 获取数据源 (从"集合"或"数组"转换为"Stream"对象)
2. 数据处理 (调用延迟方法, 编写处理方案)
3. 获得结果 (调用终结方法, 启动开关)
2. 集合转换为Stream流对象
// List集合的Stream
List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<>();
// Set集合的Stream
Stream<String> setStream = set.stream();
Map<String,String> map = new HashMap<>();
// 键的集合的Stream
Stream<String> keyStream = map.keySet().stream();
// 值的集合的Stream
Stream<String> valueStream = map.values().stream();
// 键值对Stream
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
// 数组转换为Stream流对象
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
String[] array = {"a", "b", "c"};
Stream<String> arrayStream = Stream.of(array);
3. Stream API
延迟方法: (具有延迟执行的特性)
返回值类型"是Stream"类型的方法, 支持链式调用
Stream filter(): 过滤
Stream map(): 映射/转换
Stream limit(): 截取
Stream skip(): 跳过
终结方法:
返回值类型"不是Stream"类型的方法, 不支持链式调用
void forEach(): 遍历
long count(): 统计
4. Stream API: 静态方法concat()合并两个流
concat(Stream<? extends T> a, Stream<? extends T> b): 合并两个流 的元素, 变成一个新的流. 两个流中的元素类型必须相同, 或有共同的父类
合并流: static Stream concat(Stream s1, Stream s2)
流转数组:
Object[] Stream对象.toArray()
流转集合:
List list = stream对象.collect(Collectors.toList());
Set set = stream对象.collect(Collectors.toSet());
Map map = stream对象.collect(Collectors.toMap(fun, fun));
5. 方法引用
方法引用能简化以下场景: (方法名后不要写小括号)
场景 格式 简化之前的Lambda 方法引用简化后
1. 通过对象名引用成员方法 对象名::成员方法名 ()->person.eat() person::eat
2. 通过类名引用静态方法 类名::静态方法名 i -> Math.abs(i) Math::abs
3. 通过super引用父类成员方法 super::父类方法名 ()->super.eat(); super::eat
4. 通过this引用本类成员方法 this::本类方法名 ()->this.eat(); this::eat
5. 引用某个类的构造方法 类名::new name->new Person(name) Person::new
6. 引用创建数组的方法 数据类型[]::new length->new int[length]; int[]::new
Day - 14 - 2018年12月1日JUnit 反射 注解
1. JUnit: 测试概述
测试分类:
1. 黑盒测试:不需要写代码, 给输入值, 看程序是否能够输出期望的值
比如你下载一个APP, 随便点点点, APP闪退了
2. 白盒测试:需要写代码的. 关注程序具体的执行流程
比如今天学习的JUnit
1.1 JUnit: @Before, @After
@Before: 修饰的方法会"在每个测试方法执行 之前"被执行
@After: 修饰的方法会"在每个测试方法执行 之后"被执行
2. 反射
2.1 反射: 概述
反射: 将类的各个组成部分, 封装为其他对象, 这就是反射机制
成员变量(字段): Field类的对象
构造方法: Constructor类的对象
成员方法: Method类的对象
Java代码在计算机中的3个阶段:
SOURCE: 源代码阶段
CLASS: 类对象阶段
RUNTIME: 运行时阶段
2.2 反射: 获取字节码对象的3种方式
获取一个类的字节码对象的3种方式:
1. Class.forName("全类名")
将字节码文件加载进内存,返回Class对象
适用场景: 多用于配置文件,将类名定义在配置文件中. 读取文件, 加载类
2. 类名.class
通过类名的属性class获取
适用场景: 多用于参数的传递 getConstructor(String.class, int.class)
3. 对象.getClass()
getClass()方法在Object类中定义
适用场景: 多用于对象的获取字节码的方式 p.getClass()
2.3 反射: Class的方法概述
// 成员方法
// 1. 获取成员变量们
Field[] getFields(): 获取所有 public 的成员变量
Field getField(String name): 获取指定名称的 public 的成员变量
Field[] getDeclaredFields(): 获取所有的成员变量, 不考虑权限修饰符
Field getDeclaredField(String name): 获取指定名称的成员变量, 不考虑权限修饰符
// 2. 获取构造方法们
Constructor<?>[] getConstructors(): 获取所有 public 的构造方法
Constructor<T> getConstructor(Class<?>... parameterTypes): 获取指定的 public 构造
方法
Constructor<?>[] getDeclaredConstructors(): 获取所有的构造方法, 不考虑权限修饰符
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 获取指定的构
造方法, 不考虑权限修饰符
// 3. 获取成员方法们:
Method[] getMethods(): 获取所有 public 的成员方法
Method getMethod(String name, Class<?>... parameterTypes) : 获取指定的 public 成
员方法
Method[] getDeclaredMethods(): 获取所有的成员方法, 不考虑权限修饰符
Method getDeclaredMethod(String name, Class<?>... parameterTypes): 获取指定的成
员方法, 不考虑权限修饰符
// 4. 获取Class对象代表的类的全类名
String getName(): 获取当前Class对象代表的类的全类名
// 5. 创建对象
T newInstance(): 使用当前类的空参构造, 创建一个对象
2.4 反射: 获取成员变量Field
Field: 表示一个成员变量
void set(Object obj, Object value): 设置指定对象的成员变量的值field.set(p1, "abc")
Object get(Object obj): 获取指定对象的成员变量的值 field.get(p1)
void setAccessible(boolean flag): 传true时忽略访问权限修饰符的安全检查. 暴力反射
field.set
2.5 反射: 获取构造方法Constructor
考虑权限修饰符
T newInstance(): 使用当前类的空参构造创建一个对象
java.lang.reflect.Constructor<T>: 表示一个构造方法
// 成员方法
T newInstance(Object... initargs): 使用当前构造方法传入参数, 创建对象 void setAccessible(boolean flag): 注意: 构造方法不能利用此方法忽略权限, 会抛异常
2.6 反射: 获取成员方法Method
java.lang.reflect.Method类: 表示一个成员方法
// 成员方法 Person p = new Person(); p.eat("adf", 123);
Object invoke(Object obj, Object... args): 使用指定对象和指定参数值调用此方法
String getName(): 获取方法名
3. 注解
3.1 注解: 概念
注解: Annotation
JDK 1.5 引入. 也叫元数据, 是一种代码级别的说明
它可以声明在包, 类, 字段(成员变量), 方法, 局部变量, 方法参数等的前面, 用来对
这些元素进行说明
注解: 说明程序的。给计算机看的
注释: 用文字描述程序的。给程序员看的
作用分类:
1. 编写文档: 通过代码里标识的注解生成文档
(生成API文档 @author @version @since @param @return)
2. 代码分析: 通过代码里标识的注解对代码进行分析 (使用反射)
(JUnit提供的 @Test @Before @After)
3. 编译检查: 通过代码里标识的注解让编译器能够实现基本的编译检查
(@Override @FunctionalInterface)