Lambda表达式:
Lambda表达式基于数学中的λ演算得名,对应java中的lambda抽象,是一个匿名函数,即没有函数名的函数。
Lambda表达式好处:
使用 Lambda 表达式可使代码变的更加简洁紧凑。并且Lambda表达式可和Stream API等相结合,使代码更加简洁紧凑。Lambda 表达式经常用来替代部分匿名内部类。
Lambda表达式的语法
(parameters) -> expression或 (parameters) ->{ statements; }
参数:要重写的方法的形参列表
-> :lambda运算符
表达式/语句体:要实现的方法的方法体
Lambda表达式的本质:
Lambda 表达式是一种匿名函数(不是匿名内部类),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。它实质属于函数式编程的概念。
Lamdba表达式的引入
作用:Lamdba表达式的作用就是为了简化匿名内部类
package Demo;
public class Demo3 {
public static void main(String[] args) {
//方式C:使用匿名内部类,实现接口
Fu fu = new Fu() {
@Override
public void add() {
System.out.println("add方法内部类");
}
};
fu.add();
System.out.println("---------------------------");
//此方法称为Lamdba表达式,():相当于add方法中的形参,{}:相当于add方法中的方法体
Fu f = ()->{
System.out.println("Lamdba中的aa方法");
};
f.add();
}
//方式B:使用内部类,实现对应接口,重写add方法
class Zi2 implements Fu{
@Override
public void add() {
System.out.println("add");
}
}
}
interface Fu{
void add();
}
//方式A:定义一个类重写抽象方法
class Zi implements Fu{
@Override
public void add(){
}
}
函数式接口
函数式接口:接口中只能有一个抽象方法,其他的可以有default,static,Object里继承的方法等.
作用:在java这种主要用在Lamdba表达式和方法引用(想使用Lamdba表达式,接口必须为函数式接口).
内置的函数式接口
1.Consumer:消费型接口(void accept(T t)).有参数,无返回值
2.Supplier:供给型接口(T get()).只有返回值,没有参数.
3.Function<T.R>:函数型接口(R apply(T t)).输入一个,输出两个.
4.Predicate:断言型接口(boolean test(T t))。输入一个参数,输出一个boolean类型得返回值
函数式接口 | 方法名 | 输入参数 | 输出参数 | 作用 |
---|---|---|---|---|
消费型接口Consumer | void accept(T t) | T | void | 对类型为T的对象进行操作 |
供给型接口Supplier | T get() | void | T | 返回类型为T的对象 |
函数型接口Function | R apply(T t) | T | R | 对类型为T的对象进行操作,返回类型为R的对象 |
断言型接口Predicate | boolean test(T t) | T | boolean | 对类型为T的对象进行操作,返回布尔类型结果 |
Stream使用
Stream方法使用
求1+2+3+…+100 = ? 不使用循环和递归
package Demo;
import java.util.OptionalInt;
import java.util.stream.IntStream;
public class Reduce {
public static void main(String[] args) {
OptionalInt op = IntStream.rangeClosed(1,100).reduce((a,b) -> a + b);
int n = op.getAsInt();
System.out.println(n);
}
}
生成随机10个1-100之间的整数流Stream<Integer>,并求出偶数和
package Demo;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Streamrand {
public static void main(String[] args) {
Stream<Integer> f = IntStream.generate(()->new Random().nextInt(1,101)).limit(10).filter(e->e%2==0).boxed();
List<Integer> list = f.toList();
System.out.println(list);
int sum = list.stream().mapToInt(x -> x).sum();
System.out.println(sum);
}
}
Optional容器
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方 法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null.Optional提供很多有用的方法,这 样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。
Optional无法被序列化。所以不要试图将Optional作为方法参数进行定义,也不要在类 当中声明Optional 类型的成员变量.Optional通常只作为方法的返回值,用来规避空指针异 常。 在使用Optional时,应该使用函数式的编程风格。
lambda表达式双冒号
双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名.
这里只是方法名,方法名的后面没有括号“()”。--------> 这样的式子并不代表一定会调用这个方 法。这种式子一般是用作Lambda表达式,Lambda有所谓的懒加载,不要括号就是说,看情况调用方法。
表达式:person ->person.getAge();可以替换为 Person::getAge
表达式:()->new HashMap<>();可以替换为HashMap::new
表达式:()->Math.random();可以替换为Math::random