java 8 函数式接口_Java8新特性, Lambda表达式与函数式接口

Java8的新特性有哪些

7008f8efa6883fca4fa47d9f4751e9cc.png

新特性的特征:

 速度更快

 代码更少(增加了新的语法:Lambda 表达式)

 强大的 Stream API

 便于并行

 最大化减少空指针异常:Optional

 Nashorn引擎,允许在JVM上运行JS应用

lambda表达式

什么是lambda表达式?

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以

传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了

提升

为什么要有lambda表达式?

Lambda表达式。它可以让你很简洁地表示一个行为或传递代码。现在你可以把Lambda 表达式看作匿名功能,它基本上就是没有声明名称的方法,但和匿名类一样,它也可以作为参 数传递给一个方法。

哪些场景可以使用到lambda表达式?

?????

首先我们看下再没有使用lambda的时候使用匿名内部类的对比

lambda与匿名内部类对比

//匿名内部类

Comparator c1 = new Comparator() {

@Overridepublic intcompare(Integer t1, Integer t2) {returnInteger.compare(t1,t2);

}

};int compareNumOne = c1.compare(12,13);

System.out.println(compareNumOne);//-1

System.out.println("==========Lambda==========");//lambda表达式

Comparator c2 = (c3,c4) ->Integer.compare(c3,c4);int compareNumTwo = c2.compare(11,10);

System.out.println(compareNumTwo);//1

可以看出lambda表达式简洁了很多,直接了,不像以前这么难懂 还有一大堆的内部逻辑

匿名内部类

Button button = new Button("Send");

button.setOnAction(new EventHandler() {

public void handle(ActionEvent event) {

label.setText("Sent!!");

}

});

这里,setOnAction方法的行为就用EventHandler参数化了。用Lambda表达式的话,看 起来就是这样:

button.setOnAction((ActionEvent event) -> label.setText("Sent!!"));

上面可以看出lambda使用起来很方便的  简单明了

lambda的使用

lambda的结构

3b1587750d1c29392825505c639020a5.png

 参数列表——这里它采用了Comparator中compare方法的参数,两个Apple。

 箭头——箭头->把参数列表与Lambda主体分隔开。

 Lambda主体——比较两个Apple的重量。表达式就是Lambda的返回值了。

1.举例: (o1,o2) ->Integer.compare(o1,o2);* 2.格式:* ->:lambda操作符 或 箭头操作符* ->左边:lambda形参列表 (其实就是接口中的抽象方法的形参列表)* ->右边:lambda体 (其实就是重写的抽象方法的方法体)

Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操 作符。这个操作符为 “->” ,该操作符被称为 Lambda 操作符 或箭头操作符。

它将 Lambda 分为两个部分:

左侧:指定了 Lambda 表达式需要的参数列表

右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即 Lambda 表达式要执行的功能。

下面给出了Java 8中五个有效的Lambda表达式的例子

53db1123b49bb93d490c9ed6f9261c6d.png

Lambda表达式的使用(分六种)

语法格式一:无参,无返回值

Runnable r1 =  () -> {System.out.println("Hello Lambda");};

r1.run();

语法格式二:Lambda需要一个参数,但是没有返回值

Consumer con = (String s) -> {System.out.println(s);};

con.accept("value");

语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”

Consumer con = (s) -> {System.out.println(s);};

con.accept("value");

语法格式四:Lambda若只需要一个参数,参数的小括号可以省略

Consumer con = s -> {System.out.println(s);};

con.accept("value");

语法格式五:Lambda需要两个以上的参数,多条执行语句,并且可以有返回值

Consumer con = (x,y) -> {

System.out.println(x);

return x.compareTo(y);

}

语法格式六:当Lambda体只有一条语句时,return与大括号

Comparator com = (o1, o2) -> o1.compareTo(o2);

com.compreTo(10,13);

//语法格式一:无参,无返回值

@Testpublic voidTestPOne(){

Runnable r1= newRunnable() {

@Overridepublic voidrun() {

System.out.println(" I'm one");

}

};

r1.run();

System.out.println("=======lambda======");

Runnable r2= () -> System.out.println("I'm lambda'One");

r2.run();

}//语法格式二:Lambda 需要一个参数,但是没有返回值。

@Testpublic voidTestTwo(){

Consumer con1 = new Consumer() {

@Overridepublic voidaccept(String s) {

System.out.println(s);

}

};

con1.accept("老王");

System.out.println("=======lambda======");

Consumer con2 = (String s1) ->{System.out.println(s1);};

con2.accept("我是lambda老王");

}//语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”//类型推断想我们之前遇到的泛型和数组一样

/*Consumer con = new Consumer<>(); // 省略后面的String类型

int [] len = new int [] {1,2,3}; 可以 写成 int [] len = {1,2,3}*/@Testpublic voidTestThree(){

Consumer con = new Consumer() {

@Overridepublic voidaccept(String s) {

System.out.println(s);

}

};

con.accept("老王头");

System.out.println("=======lambda======");

Consumer con1 = (s) ->{ System.out.println(s); };

con1.accept("吾乃lambda老王头");

}//语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略

@Testpublic voidTestFour(){

Consumer con = new Consumer() {

@Overridepublic voidaccept(String s) {

System.out.println(s);

}

};

con.accept("老刘");

System.out.println("=======lambda======");

Consumer con1 = s ->{System.out.println(s);};

con1.accept("吾乃lambda老刘");

}//语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

@Testpublic voidTestFive(){

Comparator com = new Comparator() {

@Overridepublic intcompare(Integer o1, Integer o2) {

System.out.println(o1);

System.out.println(o2);returno1.compareTo(o2);

}

};

System.out.println(com.compare(13, 14));

System.out.println("=======lambda======");

Comparator com1 = (l1,l2) ->{

System.out.println(l1);

System.out.println(l2);returnl1.compareTo(l2);

};

System.out.println(com1.compare(11, 10));

}//语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略

@Testpublic voidTestSix(){//原有

Comparator com = (o1, o2) -> {returno1.compareTo(o2);};

System.out.println(com.compare(10, 11));//优化后

Comparator com1 = (l1, l2) ->l1.compareTo(l2);

System.out.println(com1.compare(20, 10));

}

由上可以看出lambda只是修改了  以前写法的方法体 方法后面的执行和参数的传递依旧时不变的  只需要看方法体怎么改变即可。

Summary

* 3. Lambda表达式的使用:(分为6种情况介绍)*

*总结:* ->左边:lambda形参列表的参数类型可以省略(类型推断);如果lambda形参列表只有一个参数,其一对()也可以省略* ->右边:lambda体应该使用一对{}包裹;如果lambda体只有一条执行语句(可能是return语句),省略这一对{}和return关键字*

* 4.Lambda表达式的本质:作为函数式接口的实例*

* 5. 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,*这样做可以检查它是否是一个函数式接口。*

* 6. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。

函数式接口

什么是函数式接口

只包含一个抽象方法的接口,称为函数式接口。

为什么要有函数式接口

Java从诞生日起就是一直倡导“一切皆对象”,在Java里面面向对象(OOP) 编程是一切。但是随着python、scala等语言的兴起和新技术的挑战,

Java不 得不做出调整以便支持更加广泛的技术要求,也即java不但可以支持OOP还 可以支持OOF(面向函数编程)

说白了 函数式接口就是为了让java能面向函数编程而创建的

函数式接口的作用

用函数式接口可以干什么呢?Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例(具体说来,是函数式接口一个具体实现 的实例)

你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式 抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽 象方法上进行声明)。

我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检 查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个 接口是一个函数式接口。

在java.util.function包下定义了Java 8 的丰富的函数式接口

 简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是 Lambda表达式和函数式接口的关系。也就是说,

只要一个对象是函数式接口 的实例,那么该对象就可以用Lambda表达式来表示。

 所以以前用匿名实现类表  示的现在都可以用Lambda表达式来写。

726d5a7fb26905fefe2aeb282de9f157.png

自定义函数式接口

只需要在自定义的接口上加入@FunctionalInterface 注解即可让这个接口成为函数事接口

@FunctionalInterfacepublic interfaceMyInterface {public voidmethod1();

}

自定义函数接口与Lambda的使用

57d172b47308a74f0f1bf534a32804e3.png

80febc41a984e43e742b4bfca1c672d6.png

Java 内置四大核心函数式接口

fd2fc9aaf2589a3b3612fc06700eeaf2.png

其它接口

c2733724d99f4055b9c71e6875ed562a.png

Lambda与函数式接口的使用

//根据传递参数输出信息

public void happyTime(double money, Consumercon){

con.accept(money);

}//根据给定的规则,过滤集合中的字符串。此规则由Predicate的方法决定

public List filterString(List list, Predicatepre){

List filterList = new ArrayList<>();for(String s:list

) {if(pre.test(s)){ //如果参数s满足定义的Predicate的String泛型

filterList.add(s);

}

}returnfilterList;

}

@Testpublic voidTestMonday(){

happyTime(500, new Consumer() {

@Overridepublic voidaccept(Double aDouble) {

System.out.println("去隔壁洗浴中心消费"+aDouble);

}

});

System.out.println("=====lambda====");

happyTime(4000, money -> System.out.println("买了大宝剑花费"+money));

}

@Testpublic voidTestTuesday(){

List list = Arrays.asList("老王", "老张头","隔壁老王","隔壁小姐姐");

List list1 = filterString(list, new Predicate() {

@Overridepublic booleantest(String s) {return s.contains("老"); //包含老的字符串

}

});

System.out.println(list1);

List list2 = filterString(list,s -> s.contains("老") );

System.out.println(list2);

}

lambda与方法搭配使用必须满足函数式接口的要求,

下面既不是接口种的方法

24458470d2055b0d6a81265cd624589a.png

Practices

1:

b43695aa788ffe37dc0f2e9270f44407.png

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

(1) 这个Lambda没有参数,并返回void。它类似于主体为空的方法:public voidrun() {}。

(2) 这个Lambda没有参数,并返回String作为表达式。

(3) 这个Lambda没有参数,并返回String(利用显式返回语句)。

(4) return是一个控制流语句。要使此Lambda有效,需要使花括号,如下所示: (Integer i) -> {return "Alan" +i;}。

(5)“Iron Man”是一个表达式,不是一个语句。要使此Lambda有效,你可以去除花括号 和分号,如下所示:(String s) -> "Iron Man"。或者如果你喜欢,可以使用显式返回语 句,如下所示:(String s)->{return "IronMan";}。

View Code

2: 下面哪些接口是函数式接口?

public interfaceAdder{int add(int a, intb);

}public interface SmartAdder extendsAdder{int add(double a, doubleb);

}public interface Nothing{ }

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

答案:只有Adder是函数式接口。 SmartAdder不是函数式接口,因为它定义了两个叫作add的抽象方法(其中一个是从 Adder那里继承来的)。 Nothing也不是函数式接口,因为它没有声明抽象方法。

View Code

.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值