文章目录
一、概述
- 接口中默认方法修饰为普通方法
在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的,由于这些修饰符都是默认的。
接口定义方法:public 抽象方法 需要子类实现
接口定义变量:public、static、final
在JDK 1.8开始 支持使用static和default 修饰 可以写方法体,不需要子类重写。
方法:
普通方法 可以有方法体。
抽象方法 没有方法体需要子类实现 重写。
二、Lambda表达式
1、什么是lambda表达式?
- LAMBADA 好处: 简化我们匿名内部类的调用。
- Lambda+方法引入: 代码变得更加精简。
- Lambda 表达式(lambda expression)是一个匿名函数,简化我们调用匿名函数的过程。
2、Lambda表达式的规范
- 使用Lambda表达式依赖于函数接口
1. 在接口中只能够允许有一个抽象方法
2. 在函数接口中定义object类中方法
3. 使用默认或者静态方法
4. @FunctionalInterface 表示该接口为函数接口
Java中使用Lambda表达式的规范,必须是为函数接口
函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口
- 函数接口定义
1.在接口中只能有一个抽象方法
2.@FunctionalInterface 标记为该接口为函数接口
3.可以通过default 修饰为普通方法
4.可以定义object类中的方法
- Java系统内置那些函数接口
消费型接口:
Conusmer<T>
void accept(T t);
BiConusmer<T,U>
void accept(T t,U u);//增加一种入参类型
供给型接口
Supplier<T>
void get();
函数型接口
Function<T ,R>
R apply(T t);
UnaryOperator<T>
T apply(T t);//入参与返回值类型一致
BiFunction <T ,U,R>
R apply(T t,U u);//增加一个参数类型
BinaryOperator<T>
T apply(T t1,T t2);//l两个相同类型入参与同类型返回值
ToIntFunction<T>//限定返回int
ToLongFunction<T>//限定返回long
ToDoubleFunction<T>//限定返回double
IntFunction<R>//限定入参int,返回泛型R
LongFunction<R>//限定入参long,返回泛型R
DoubleFunction<R>//限定入参double,返回泛型R
断言型接口
Predicate<T>
boolean test(T t);
- JDK中自带的函数接口
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
我们也可以使用@FunctionalInterface修饰为函数接口
3、Lambda表达式基础语法
- 基础语法:
()---参数列表
-> 分隔
{} 方法体
(a,b)->{
}
():函数方法参数列表
->分隔 {}方法体
(a,b)->{
Sout(a,b)
}
Lambda语法:
():参数列表
->分隔
{}:方法体
()->{}
4、Lambda方法引入
- 什么是方法引入?
方法引入:需要结合lambda表达式能够让代码变得更加精简。
1.匿名内部类使用
2.Lambda调用匿名内部类
3.方法引入
方法引入
1.静态方法引入: 类名::(静态)方法名称
2.对象方法引入 类名:: 实例方法名称
3.实例方法引入 new对象 对象实例::方法引入
4.构造函数引入 类名::new
需要遵循一个规范:
方法引入 方法参数列表、返回类型与函数接口参数列表与返回类型必须要保持一致。
方法引用提供了非常有用的语法,可以直接引用已有的java类或对象的方法或构造器。方法引用其实也离不开Lambda表达式,与lambda联合使用 ,方法引用可以使语言的构造更加紧凑简洁,减少冗余代码。
方法引用提供非常有用的语法,可以直接引用已有的java类或者对象中方法或者构造函数,
方法引用需要配合Lambda表达式语法一起使用减少代码的冗余性问题。
- 方法引入规则
方法引入实际上就是lambda表达式中直接引入的方法。
必须遵循规范:引入的方法参数列表返回类型必须要和函数接口参数列表、返回
类型保持一致。
-
静态方法引入
-
对象方法引入
-
实例方法引入
-
构造方法引入
import com.google.common.base.Function;
import lombok.Data;
import lombok.ToString;
/**
* @ClassName: Test41
* @Author: gj
* @Description: lambda表达式
* @DateTime: 2023/8/28 11:02
*/
public class Test41
{
public static void main(String[] args) {
//静态方法引入
Demo01 demo01 = Test41::staticMethod;
demo01.get();
//对象方法引入
Function<String, Integer> function1 = String::length;
System.out.println("对象方法引入: " + function1.apply("lambda"));
//实例方法引入
Test41 test41 = new Test41();
Demo02 demo02 = test41::get;
demo02.get(666);
//构造方法引入
Demo03 demo03 = Student::new;
Student student = demo03.getStudent();
student.setName("张三");
student.setAge(18);
System.out.println(student);
}
@FunctionalInterface
public interface Demo01{
void get();
}
public static void staticMethod()
{
System.out.println("我是静态方法");
}
@FunctionalInterface
public interface Demo02{
void get(int a);
}
public void get(int a)
{
System.out.println("我是实例方法: " + a);
}
@Data
@ToString
public static class Student{
private String name;
private int age;
}
@FunctionalInterface
public interface Demo03{
Student getStudent();
}
}
三、Stream流
1、什么是stream流?
-
Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
-
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
-
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
-
Stream :非常方便精简的形式遍历集合实现 过滤、排序等。
2、Stream创建方式
- parallelStream为并行流采用多线程执行
- Stream采用单线程执行
- parallelStream效率比Stream要高。
3、Stream流常用方式
-
Stream将list转换为Set
-
Stream将list转换为Map
-
Stream将Reduce 求和
-
Stream Max和Min
-
Stream Match 匹配
-
Stream For循环
-
Stream过滤器
-
Stream排序 sorted
-
Stream limit和skip
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @ClassName: Test42
* @Author: gj
* @Description:
* @DateTime: 2023/8/28 14:46
*/
public class Test42
{
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
User user1 = new User();
user1.setUserId("1001");
user1.setName("张三");
user1.setAge(18);
userList.add(user1);
User user2 = new User();
user2.setUserId("1002");
user2.setName("李四");
user2.setAge(19);
userList.add(user2);
User user3 = new User();
user3.setUserId("1003");
user3.setName("王五");
user3.setAge(20);
userList.add(user3);
//- Stream将list转换为Set
Set<User> userSet = userList.stream().collect(Collectors.toSet());
//- Stream将list转换为Map (key:userId values:user)
Map<String, User> userMap = userList.stream().
collect(Collectors.toMap(User::getUserId, user -> user));
//- Stream将Reduce 求和
Optional<User> reduce = userList.stream().reduce((t1, t2) -> {
t1.setAge(t1.getAge() + t2.getAge());
return t1;
});
//- Stream Max和Min
Optional<User> min = userList.stream().
min(Comparator.comparingInt(User::getAge));
Optional<User> max = userList.stream().
max(Comparator.comparingInt(User::getAge));
//- Stream Match 匹配
boolean isName = userList.stream().
anyMatch(u -> Objects.equals("张三", u.getName()));//满足一个条件,返回true
boolean isAge = userList.stream().
allMatch(u -> 18 == u.getAge());//满足所有个条件,返回true
//- Stream For循环
userList.forEach(System.out::println);
//- Stream过滤器
List<User> users = userList.stream().
filter(u -> u.getAge() > 18).collect(Collectors.toList());//过滤年龄大于18的
//- Stream排序 sorted
List<User> userSorted = userList.stream().
sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
//- Stream limit和skip
List<User> collect = userList.stream().
skip(1).collect(Collectors.toList());//跳到指定位置获取到尾部
List<User> collect1 = userList.stream().
limit(2).collect(Collectors.toList());//从头开始,限制获取个数
}
}
四、JDK8 Optional
1、什么是Optional?
- Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
- Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
- Optional 类的引入很好的解决空指针异常。
2、Optional常用方法
- 判断参数是否为空
//判断参数是否为空
User user = new User();
//参数不能为空,false:为null true:不为null
boolean isFlag1 = Optional.ofNullable(user).isPresent();
//参数可以为空 false:为null true:不为null
boolean isFlag2 = Optional.of(user).isPresent();
- 参数为空可以设定默认值
//判断参数为null,设定指定值
String str = null;
String test = Optional.ofNullable(str).orElse("test");
- 参数实现过滤
//实现值过滤
int a = 1;
boolean present = Optional.ofNullable(a).filter(t -> t > 1).isPresent();