lambda表达式
lambda表达式
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
Java8 lambda表达式实战使用
jdk 1.8时间的api
Java junit.data这个API的缺憾,
Date date是个可变的对象,使用对象的时候要使用不可变的对象比如String和BigDecimal原对象是不可变的,只有在生成新的对象的时候才可以改变.
但是date生成的对象是可变的,破坏了对象的可变性.
LocalData代表日期只有年月日没有时分秒,如果进行操作不会改变当前对象.
LocalDateTime使用时间的时候.函数式接口
Lambda表达式是Java8中最重要的新功能之一,使用lambda表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂,lambda表达式同事还提升了对集合框架的迭代,遍历过滤数据的操作
函数式编程参数类型自动推断
new Thread(()->{System.out.println("xx");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
更好的支持多并行
熟悉泛型操作,来了解lambda表达式类型推断
函数式接口的地方都可以使用函数式接口的地方
什么是函数式接口,只有一个抽象方法的接口就是函数式接口.
默认方法是不算的
@FunctionalInterface//函数式接口的注解
interface UserMap{
//静态方法也不行,object里面的方法去定义也是不算函数式接口的,define方法除外
int insert();
}
/**
* Runable就是一个函数式接口,Callable也是函数式接口,这个还是一个带有泛型的函数表达式
* Comparetor也是函数式接口
* JDK1.8之后的函数式接口:
* Java.utils.function
* <p>
* Supplier接口这个代表的是输出函数接口
* Comsumer这个代表的是一个输入的接口,
* Bicomsumer这个代表的是两个输入的接口
* Function这个代表的是一个输入一个输出的方法一版代表输入和输出是不同类型的函数
* UnaryOperator继承Function代表一个输入和一个输出,但是这两个是相同类型
* BiFunction这个代表的是两个输入和一个输出,类型一版是不一样的(一般是不一样的)
* BinaryOperator这个是两个输入,一个输出,输入和输出的类型,相同.
* <p>
* 熟练的记住函数式接口的类型
*/
@FunctionalInterface
//函数式接口的注解,只有函数式接口可以使用这个
interface UserMap {
//静态方法也不行,object里面的方法去定义也是不算函数式接口的,define方法除外
int insert();
}
/**
* lambda表达式详解
* 语法以及如何使用,是对象是一个函数式接口的实例
* 普通接口,非函数式接口不能使用lambda表达式
*
* 后面的是抽象方法的实现逻辑,只有一个参数的时候()可以省略
* 函数内容比较多的时候{}可以省略
*
* 无参数有返回值可以null没有返回值也可以写成这个
*
* 注意事项,参数类型可以省略,参数类型不能不分省略
* 不能把函数复制给非函数式接口,不允许也不需要throws来声明他可能会抛出的异常
*
* 需要抛出异常的时候,可以需要上一级来抛出异常
*/
Runnable runnable = () ->System.out.println("xx");
Runnable runnable1 = () ->System.out.println("xx");
Runnable runnable2=()-> {
final Object o = null;
};
Callable<String> callable=()->{return "xx";};
Function<Integer,Integer> function=a->{
int sum=0;
for (int i=0;i<100;i++){
}
return sum;
};
static int exec(){
return 1;
}
Runnable runnable3=()->{};
UserMap userMap1=()->{return 6;};
new Thread(() -> {
System.out.println("xx");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Runnable runnable = () -> {
};
/**
*有参数有返回值的
*/
Function<String, Integer> function = (string) -> {
return 1;
};
//引用实例方法
Function<String,String> function1=(string)->string.toUpperCase();
function1.apply("sss");
//引用对象的实例方法,方法的引用,直接去访问已经存在的方法或者构造方法.如果抽象的方法实现敲好可以使用调用另外的一个类的方法实现,这杨就可以使用方法引用
//静态方法引用 :: 函数式接口可以调用静态方法来实现,就可以使用静态方法引用,
//只要是调用的静态方法就可以,任意的静态方法都是可以的
Supplier<String> stringSupplier=()->"";
Supplier<String> stringSupplier1=Fun::ret;
//有输入参数的
Consumer<String> consumers=PublishDialog::get;
consumers.accept("ssss");
Function<String,String> function2=PublishDialog::get;
function2.apply("");
BiFunction<String,String,Integer> biFunction=PublishDialog::get;
biFunction.apply("","");
//实例方法引用 inst::
Supplier<String> stringSupplier2=new Fun()::builderes;
//对象方法引用 ::
//构造方法引用 ::
Consumer<String> consumer=arg->arg.toUpperCase();
consumer.accept("sss");
}
PublishDialog(){
}
public void builderes(String str){
}
public static String getStr(){
return "String";
}
public static String get(String string){
return "";
}
public static Integer get(String string,String string1){
return 1;
}
static class Fun{
public static String ret(){
return "";
}
public void builderes(){
}
public void builderes(String str){
}
}
PublishDialog(){
}
public void builderes(String str){
}
public static String getStr(){
return "String";
}
public static String get(String string){
return "";
}
public static Integer get(String string,String string1){
return 1;
}
static class Fun{
public static String ret(){
return "";
}
public void builderes(){
}
public void builderes(String str){
}
}
Runnable runnable = () -> {
};
/**
*有参数有返回值的
*/
Function<String, Integer> function = (string) -> {
return 1;
};
//引用实例方法
Function<String,String> function1=(string)->string.toUpperCase();
function1.apply("sss");
//引用对象的实例方法,方法的引用,直接去访问已经存在的方法或者构造方法.如果抽象的方法实现敲好可以使用调用另外的一个类的方法实现,这杨就可以使用方法引用
//静态方法引用 :: 函数式接口可以调用静态方法来实现,就可以使用静态方法引用,
//只要是调用的静态方法就可以,任意的静态方法都是可以的
Supplier<String> stringSupplier=()->"";
Supplier<String> stringSupplier1=Fun::ret;
//有输入参数的
Consumer<String> consumers=PublishDialog::get;
consumers.accept("ssss");
Function<String,String> function2=PublishDialog::get;
function2.apply("");
BiFunction<String,String,Integer> biFunction=PublishDialog::get;
biFunction.apply("","");
//实例方法引用 inst::
Supplier<String> stringSupplier2=new Fun()::builderes;
//对象方法引用 ::
//构造方法引用 ::
Consumer<String> consumer=arg->arg.toUpperCase();
consumer.accept("sss");
//实例方法调用
Supplier<String> stringSupplier = new MainActivity()::put;
stringSupplier.get();
//除了可以调用this的方法,还是可以调用父类的方法
//supper::put;实例方法可以调用this和supper的引用
Function<String, String> function = this::put;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
function.apply("ss");
}
Consumer<String> consumer = new MainActivity()::put;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
consumer.accept("ssss");
}
/**
* 对象方法引用和实例方法引用
*/
//对象方法引用
/**
* 限制条件,抽象方法的第一个参数类型刚好是实例方法类型,必须要有输入参数,抽象方法的剩余参数,恰好是实例方法的参数
*/
//抽象方法没有输入参数,不能使用对象方法引用,比如像Runnable
//抽象方法的第一个类型必须是自定义的类型
Consumer<Too> consumer1 = (Too too) -> new Too().foo();
Consumer<Too> consumer2 = too1 -> too1.foo();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
consumer2.accept(new Too());
}
BiConsumer<Too, String> biConsumer = (too, str) -> new Too().foo(str);
/**
* 构造方法引用
* 函数可以使用构造方法来实现,就可以使用构造方法引用来实现的方式
* FIle是没有无参数的构造函数,所以不能使用构造方法引用来实现.
*
* intger没有无参数的构造函数,所以也不能使用构造方法引用来实现
*
* 方法的引用,只是对方法的引用,而不是执行方法引用
*/
Supplier<Person> supplier = () -> new Person();
Supplier<Person> supplier1 = Person::new;
Consumer<String> consumer3 = Person::new;
Function<String, Integer> function1 = Integer::valueOf;
/**
* Stream API
*
* 流就是用来操作数组的,有顺序流和集合流,并行和非并行操作,聚合,不支持索引访问,延迟计算,容易生成数组或者集合
* 支持过滤,查找,转换,汇总,聚合等操作
*/
//Stream 原中间操作和终止操作,在操作结束后才会对数据进行计算
/**
* 中间操作有哪些
* 过滤 filter
* 去重 distinct
* 排序 sorted
* 截取 limit, skip忽略
* 转换 map/flatMap
* 其他peek 中间操作记录结果
*
* 终止操作
*
* 循环forEach
* 计算min max count average
* 匹配anyMatch allMatch noneMatch findFrist findAny
* 汇聚reduce
* 收集器 toArray collect转换集合和数组
*/
/**
* 数组,结合,Stream.generate来创建,Stream.iterate来创建,其他API创建
* 只有中间操作没有进行终止操作的时候是不会进行操作的,这就是延时操作
*
* max需要传入一个比较器
* sort默认是从小到大
*
* 并行流和顺序流
* compartor可以根据字段排序
* thenComparing()多个比较器
*/
}
public static void gen1() {
int[] a = new int[]{1, 2, 3, 4, 5, 6};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Stream<int[]> stream = Stream.of(a);
stream=stream.limit(3);
}
ArrayMap<String, String> arrayMap = new ArrayMap<>();
ArrayList<Integer> arrayList = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
arrayList.stream();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Stream<Integer> stream = Stream.generate(() -> 1);//无止境的死循环,需要截取操作配合
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//parallel并行操作sequential顺序操作 内部使用forkjoinpool来实现并行操作
//ForkJoinPool(int)可以设置线程数量,一般和cpu核心数量是相同的,可以设置启动参数的变量来设置
System.setProperty("Java.util.concurrent.ForkJoinPool.common.parallelism","5");//设置并行线程数量,加上主线程会是六个线程在运行.
Stream.iterate(1,x->x+1).limit(50).parallel().sequential().collect(Collectors.toList());//无止境的死循环,需要截取操作配合,利用Collectors里面的方法来进行处理
}
// test注解是4以上的版本
String string = "";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
IntStream stream=string.chars();
}
}
class Person {
Person() {
}
/**
* 这种就不能使用构造函数引用
*
* @param str
*/
Person(String str) {
}
Person(Integer str) {
}
}
interface Execute {
public void foo(String str1, String str);
}
class Too {
public void foo(String str) {
}
public void foo() {
}
}
public String put() {
return "";
}
public String put(String str) {
return "";
}
- 点赞
- 收藏
- 关注作者
评论(0)