1.Lambda表达式
eg 1:
//原始写法
Runnable r1 = new Runnable(){
@Override
public void run(){
System.out.println("helloworld");
}
}
r1.run();
//Lambda表达式
Runnable r2 = () -> System.out.println("helloworld");
r2.run();
eg 2:
//原始写法
Comparator<Integer> com1 = new Comparator(){
@Override
public int compare(Integer o1, Integer o2){
return Integer.compare(o1, o2);
}
}
System.out.println(com1.compare(12, 21));
//Lambda表达式
Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
System.out.println(com2.compare(22, 21));
//方法引用
Comparator<Integer> com3 = Integer :: compare;
System.out.println(com3.compare(23, 21));
格式
形参列表 -> Lambda体
-> :Lambda操作符、箭头操作符
形参列表 :接口中抽象方法的形参列表
Lambda体 :重写的抽象方法的方法体
格式一 无参无返回值
() -> 方法体
格式二 一个参数无返回值
eg:
Consumer<String> c = (String s) -> {方法体};
格式三 数据类型可以省略,因为可以由编译器推断出来,称为“类型推断”
eg:
Consumer<String> c = (s) -> {方法体};
格式四 只需要一个参数时,小括号可以省略
eg:
Consumer<String> c = String s -> {方法体};
格式五 两个或以上参数,多条语句,可以有返回值
eg:
Comparator<Integer> com = (o1, o2) -> {
语句1;
语句2;
语句3;
return o1.compareTo(o2);
}
System.out.println(com.compare(22, 21));
格式六 Lambda体只有一条执行语句,如果有{}或return,两者都可以省略
eg:
Comparator<Integer> com = (o1, o2) -> o1.compareTo(o2);
Lambda本质
作为函数式接口的实例
要求
Lambda实现的接口只有一个抽象方法
应用
以前用匿名实现类做的都可以用Lambda代替
2.函数式Functional接口
如果一个接口只声明了一个抽象方法
@FunctionalInterface since 1.8
可以帮助进行校验,防止出错
Java内置四大函数型接口
接口名 中文名 参数名称 返回值 方法
Consumer<T> 消费型接口 T void void accept(T t)
Supplier<T> 供给型接口 无 T T get()
Function<T, R> 函数型接口 T R R apply(T t)
Predicate<T> 断定型接口 T boolean boolean test(T t)
3.方法引用
方法引用
eg:
Comparator<Integer> com3 = Integer :: compare;
System.out.println(com3.compare(23, 21));
何处使用?
当传递给Lambda体的操作已经有实现的方法,可以使用方法引用
有什么要求?
接口中的抽象方法的返回值类型和参数列表与方法引用的方法的返回值类型和参数列表类型相同
格式
类(或对象) :: 方法名
三种情况
情况一 对象 :: 非静态方法
情况二 类 :: 静态方法
情况三 类 :: 非静态方法
//情况一 对象 :: 非静态方法
//Consumer中的void accept(T t)
//PrintStream中的void println(T t)
//Lambda
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("helloworld");
//方法引用
PrintStream ps = System.out;
Consumer<String> con1 = ps :: println;
con1.accept("helloworld");
//情况二 类 :: 静态方法
//Comparator中的int compare(T1 t1, T2 t2)
//Inteegr中的static int compare(Integer t1, Integer t2)
//Lambda
Comparator<Integer, Integer> com1 = (t1, t2) -> Integer.compare(t1, t2);
com1.compare(12, 21);
//方法引用
Comparator<Integer, Integer> com2 = Integer :: compare;
com2.compare(12, 21);
//Function R apply(T t)
//Math static Long round(Double d)
//Function<Arg, Return>
Function<Double, Long> fun1 = new Function<>(){
@Override
public Long apply(Double d){
return Math.round(d)
}
}
fun1.apply(3.14);
//
Function<Double, Long> fun2 = d -> Math.round(d);
fun2.apply(3.14);
//
Function<Double, Long> fun3 = Math :: round;
fun3.apply(3.14);
//情况三 类 :: 非静态方法
//Comparator中的int compare(T t1, T t2)
//String中的int t1.compareTo(t2)
//Lambda
Comparator<String, String> com1 = (s1, s2) -> s1.compareTo(s2);
com1.compare(s1, s2);
//方法引用
//第一个参数作为调用方法的对象,第二个参数作为方法的形参
Comparator<String, String> com2 = String :: compareTo;
com2.compare(s1, s2);
4.构造器引用
构造器引用
//Supplier中的T get()
//Employee中的构造器Employee()
//Lambda
Supplier<Employee> sup1 = ()-> new Employee();
Employee emp1 = sup.get();
//构造器引用
Supplier<Employee> sup2 = Employee :: new;
Employee emp2 = sup.get();
数组引用
//Lambda
Function<Integer, String[]> fun1 = (length) -> new String[length];
String[] strs1 = fun1.apply(20);
//数组引用
Function<Integer, String[]> fun2 = String[] :: new;
String[] strs2 = fun2.apply(20);
5.Stream API
java.util.stream
功能:操作(集合、数组等容器中的)数据
操作步骤:
1创建stream
一个数据源,获得一个流
2中间操作
一个中间操作链,对数据源的数据进行处理
3终止操作
执行终止操作时,才执行中间操作链,产生结果。之后不会再被使用。
Stream API的使用
1)创建Stream API的四种方式
通过集合Collection
Java8中的Collection被扩展,提供了两个获取流的方法
default Stream<E> stream() 返回一个顺序流
default Stream<E> parallelStream() 返回一个并行流
eg:
List<Employee> empList = EmployeeData.getEmployeeList();
Stream<Employee> stream = empList.stream(); //顺序流
Stream<Employee> parallelStream = empList.parallelStream(); //并行流
通过数组
Java8中的Arrays,可以获得数组流
static Stream<T> stream(T[] array) 返回一个流
eg: 基本数据类型
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
引用数据类型
Stream<Employee> stream = Arrays.stream(empArr);
通过Stream的of()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
创建无限流
创建无限个元素对应的Stream
迭代
public static <T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
eg:
2)中间操作
筛选与切片
filter(Predicate p) 接收Lambda,从流中排除某些元素
limit(n) 截断流,使其操作不超过指定数量
skip(n) 跳过元素,返回一个扔掉了前n个元素的流。若元素中元素不足n个,则返回一个空流
distinct() 筛选,通过流所生成元素的hashCode()和equals()去除重复元素
映射
map(Function f) 接受一个函数作为参数,该函数提取信息或做处理,将原来集合中的元素映射到一个新的元素
flatMap(Function f) 接受一个函数作为参数,把流中每个值换成另一个流,然后把所有流连成一个流 类似List的addAll()
排序
sorted() 产生一个新流,按自然顺序排序
sorted(Comparator com) 产生一个新流,按比较器规则排序
3)终止
1匹配与查找
boolean allMatch(Predicate p) 是否匹配所有元素
boolean anyMatch(Predicate p) 是否至少一个元素匹配(满足条件)
boolean noneMatch(Predicate p) 是否全部不匹配
findFirst() 返回流中第一个元素
findAny() 返回流中任意元素,顺序流和并行流返回结果不同
count()
max(Comparator com)
min(Comparator com)
forEach(Consumer c) 内部迭代
2归约
reduce(T identity, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值,返回T
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值,返回Optional<T>
map-reduce模式
3收集
collect(Collector c)
6.Optional类
java.util.Optional是一个容器类
创建Optional类的对象
Optional.of(T t) 要求t不是null
Optional.empty()
Optional.ofNullable(T t)
判断是否包含对象
boolean isPresent() 判断是否包含对象
void ifPresent(Consumer<? super T> consumer) 如果有值,将此值作为参数传给Consumer接口的实现方法
获取Optional容器的对象
T get() 如果值(Optional中的value)不为null,返回值,如果无值(value为null),抛出异常
T orElse(T other) 有值返回值,无值返回other
T orElseGet(Supplier<? extends T> other) 有值返回值,无值返回other提供的对象
T orElseThrow(Supplier<? extends X> exceptionSupplier) 有值返回值,无值抛出other提供的异常
标签:Stream,compare,java,JDK,Comparator,stream,eg,019,Lambda
From: https://www.cnblogs.com/zhengcg/p/16651539.html