1.lambda表达式
Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)
1.1 使用场景
interface Action{
void say();
}
//
public class Test{
public void test(Action a){
a.say();
}
public static void main(String[] args) {
Test t = new Test();
// t 如何调用test(Action a)方法实现输入helloWorld字符串
}
}
解决方式:
1.创建接口Action的实现类,实现say()方法。
2.创建接口Action的匿名内部类对象,实现say() 方法
可不可以以把实现的say()方法作为参数传递到test(Action a)中呢?
Action a = public void say(){System.out.println("hello World");}
简化代码:
Action a = ()-> System.out.println("hello World"); //lambda表达式
第三种解决方式:
t.test(() -> System.out.println("test1"));//函数作为参数传递到方法中
1.2 lambda表达式的语法要求:
语法结构:(variable)->action
variable : 方法的变量名称
-> : 分割符
action : 方法体
方法体可以是一个表达式
() -> System.out.println("hello");
方法体可以是一个代码块,表示方法的开始和结束。
C c3 = () -> {};
C c3 = () ->{
System.out.println("hello");
System.out.println("world");
};
方法体可以省略到return 关键字
E e2 = (int id,String name)->0;
变量名称可以包含多个参数
E e = (int id,String name)->{return 0;};
变量名称只有一个时,可以省略括号
F f = id->System.out.println(“hello”);
变量名称可以省略到参数类型
F f = id->System.out.println(“hello”)
我们将Action接口称为函数式接口
函数式接口
(1) 使用 @FunctionalInterface 注解可以判断当接口不符合函数式接口定义的时候,编译器会报错。
(2) 接口中只有一个抽象方法,可以有多个非抽象的方法。
常用的函数式接口
java.util.function.Predicate
java.util.function.Function<T, R>
2.接口的默认方法与静态方法
(1)接口中可以有实现的方法。只需要使用default或者static修饰即可。
(2)default和static 不能同时修饰同一个方法。
(3)实现的方法不需要接口的实现类必须去实现,可以直接调用。
2.1 定义默认方法:使用default关键字修饰方法。
public interface Action{
default void test(){
System.out.println("test");
}
}
2.2 定义静态方法:使用static关键字修饰方法。
public interface Action{
static void test(){
System.out.println("test");
}
}
2.3 直接使用接口中实现的方法
public class Test implements Action{
public static void main(String[] args) {
Test t = new Test6();
t.test();// 调用default方法
Action.method();//调用static方法
}
}
//Action接口
interface Action{
default void test(){
System.out.println("test");
}
static void method(){
System.out.println("method");
}
}
2.4 查看List接口和Collection接口代码。看到接口中默认方法。
3.Stream(流)
流是java8中的新成员。它允许你声明性方式处理数据集合。我们可以把流看做遍历数据集的高级迭代器。
3.1 使用场景
ArrayList集合
已知在userList集合中存放20个User对象。筛选出工资大于5000的员工。并对筛选出的员工按照员工的工号从小到大排序。
实现编程(外部迭代):
//1.list 保存筛选后的对象 中间容器
//2. user()---> List -筛选-->list--排序-->list
ArrayList<User> list = new ArrayList<>();
for (User user : userList) {
if(user.getSalary()>5000){
list.add(user);
}
}
Collections.sort(list, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId()-o2.getId();
}
});
使用流对象编程(内部迭代):
List<User> list = userList.stream()
.filter(u -> u.getSalary()>5000)
.sorted((o1,o2)->o1.getId()-o2.getId())
.collect(Collectors.toList());
3.1 流是“从支持数据处理操作的源生成的一系列元素”。
3.2 流利用内部迭代:迭代通过filter、map、sorted等操作被抽象掉了。
3.3 流操作有两类:中间操作和终端操作。
java.util.stream.Stream接口定义了流操作。
操作分类:1.中间操作: filter map limit
2.终端操作: collect forEach count
中间操作和终端操作演示:
list—>filter---->map---->limit---->collect
中间操作: 1.返回另一个流
Stream filter(Predicate<? super T> predicate);
2.链式调用中间操作(流水线),不会产生任何结果,除非调用终端操作
终端操作:1.会返回一个非流的值,并处理流水线以返回结果。
4.Optional类
作用:用来解决空指针异常的类
4.1 构造器private修饰,不能直接创建对象,使用静态方法创建对象
empty() : 创建空的Optional对象
of(T value) :不允许value值空
ofNullable(T value) :允许value值空
4.2 常用方法
isPresent() :如果值存在则方法会返回true,否则返回 false。