Lambda 表达式语法
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。 可以使用注解 @FunctionalInterface 修饰,用来定义必须是此接口必需是函数式接口
Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表,右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体。
new Runnable(){
@Override
public void run() {
}
};
现在可以这样写
//无参数 无返回值
Runnable r = () -> System.out.println("cc");
r.run();
//有一个参数,并且无返回值
Consumer cc = (x) -> System.out.println(x);
cc.accept("传参值x然后答应");
//有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
Comparator<Integer> comparator=(x,y)-> {
System.out.println("cc");
return Integer.compare(x,y);
};
Lambda 体中只有一条语句, return 和 大括号都可以省略不写
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
* Consumer<T> : 消费型接口
* void accept(T t);
*
* Supplier<T> : 供给型接口
* T get();
*
* Function<T, R> : 函数型接口
* R apply(T t);
*
* Predicate<T> : 断言型接口
* boolean test(T t);
1
Consumer<String> consumer = (f) -> System.out.println(f);
consumer.accept("cccc");
2
Supplier<String> id = () -> {
System.out.println("cc");
return "cccaa";
};
String s = id.get();
System.out.println(s);
3
Function<String,String> as=(x) -> {
System.out.println(x);
return x;
};
as.apply("11");
4
Predicate<Integer> predicat=(x)-> {
System.out.println("cc");
return x>3;
};
boolean test = predicat.test(1);
方法引用
方法引用:若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用(可以将方法引用理解为 Lambda
表达式的另外一种表现形式)
3种
* 1. 对象的引用 :: 实例方法名
*
* 2. 类名 :: 静态方法名
*
1和2 一样
-----------------------------------------------------------
(1)Consumer<String> consumer = System.out::println;
consumer.accept("cc");
原因void accept(T t); 与 void println(String x) 它们的参数列表与返回值一致
demo:
Supplie<String> getName1 = methodRef::getName;// 参数为空,返回值为String 类型
Consumer<String> setName1 = methodRef::setName;
demo:
Comparator<Integer> compare = Integer::compare;
int compare1 = compare.compare(1, 3);
System.out.println(compare1);
Users users=new Users("21",21);
Supplier<String> getName = users::getName;
System.out.println((getName.get()));
-------------------------------------
(3)类名 :: 实例方法名
若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式:
ClassName::MethodName
Function<Employee, String> fun = (e) -> e.show();
Function<Employee, String> fun2 = Employee::show;
==============================================================
构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!
Supplier<Users> supplier=Users::new; //supplier接口中的函数没有参数,所以调用无参函数
一个参数 Function函数式接口
数组引用
Function<Integer, Employee[]> fun2 = Employee[] :: new;
Employee[] emps = fun2.apply(20);
StreamAPI
三步骤 1 创建流 2 中间操作 3 终止操作
创建流
//1. Collection 提供了两个方法 stream() 与 parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
//2. 通过 Arrays 中的 stream() 获取一个数组流
Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);
//3. 通过 Stream 类中静态方法 of()
Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);
4 //迭代
Stream<Integer> stream = Stream.iterate(0, (x) -> x + 2);//无限流
stream.forEach(System.out::println);
//生成
Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);
stream.foreach 需要一个消费性接口 ,System.out::println 返回一个消费性接口
中间操作 延迟加载 不会执行任何操作,知道触发终止操作
filter 断言型接口
Predicate<Integer> tMyPredicate = (x) -> x > 3;
tMyPredicate.test(4);
emps.stream().filter((e) -> e.getAge()>35).forEach(System.out::println);
limit(long maxSize)
截断流,使其元素不超过给定数量。
skip(long n)
跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素
不足 n 个,则返回一个空流。与 limit(n) 互补
emps.stream().filter((e) -> {
System.out.println("cc");
return e.getAge()>18;}).skip(2).forEach(System.out::println);
distinct()
筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
map(Function f)
接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
List<String> strings = Arrays.asList("aa", "cc", "dd");
strings.stream().map(s -> s.toUpperCase()).forEach(System.out::println);
意思是 集合中的所有元素都应用到map中的函数上。
Function function=(x)-> x;
flatMap(Function f)
接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
sorted()
产生一个新流,其中按自然顺序排序 按照实现comparable 接口的排序,字典排序
sorted(Comparator comp)
产生一个新流,其中按比较器顺序排序 定会排序
练习
public static Stream<Integer> fi(String stream) 函数型接口
Function<String, Stream<Integer>> fi = TestStream::fi;
public static Stream<Integer> fi() 供给型
Supplier<Stream<Integer>> fi = TestStream::fi;
类名 :: 实例方法名
若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式:
ClassName::MethodName
Function<Employee, String> fun = (e) -> e.show();
Function<Employee, String> fun2 = Employee::show;
BiPredicate<String, String> bp = (x, y) -> x.equals(y);
BiPredicate<String, String> bp2 = String::equals;
终止操作
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch( (Predicate p) ) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
findAny() 返回当前流中的任意元素
count()返回流中元素总数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
boolean b = emps.stream().allMatch((x) -> x.getStatus().equals(Employee.Status.BUSY));
其实 x就是当前的对象
Employee employee = emps.stream().findFirst().get();
//其中emps.stream().findFirst()返回一个option容器类
emps.stream().sorted((x,y)->
Integer.compare(x.getAge(),y.getAge()) //使用comparator
).forEach(System.out::println);
收集
List<String> collect = emps.stream().map(Employee::getName).collect(Collectors.toList());
collect.forEach(System.out::println); Employee的 名字收集到集合中
归约
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0, (x, y) -> x + y); x+y ->x 然后加上y
//分组
Map<Status, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
optional容器类
常用方法:
Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
isPresent() : 判断是否包含值
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
----------------------------------------------------------
// Optional<Object> o = Optional.of(null);
// System.out.println(o);
Optional<Object> empty = Optional.empty();
System.out.println(empty);
Optional<Employee> employee = Optional.ofNullable(null);
System.out.println(employee.get())
if (employee.isPresent()){
employee.get();//有值就获取
}
Optional<Employee> op = Optional.ofNullable(null);
Employee employee = op.orElse(new Employee(1, "22", 21, 21.0Employee.Status.FREE));
System.out.println(employee); 有值得时候获取默认值,没有时候获取orelse的值