1.Lambda表达式
面向对象的基础上支持函数式编程
-
1.1 约束:
接口有且仅有一个抽象方法,如果存在两个抽象方法,则无法使用函数式编程。
-
接口有且仅有一个抽象方法,且想要转化为lambda表达式,加注解 @FunctionalInterface——表明其是一个函数接口。此注解会检查该接口中是否只存在一个抽象方法,当出现多个抽象方法时,会编译报错。
-
1.2 语法:
- 1.1.1
如果实现抽象方法的方法体中只有一条命令,大括号可以省略
package com.qqycc;
/**
* 方法体只有一条命令的Lambda
* Author: qqy
*/
@FunctionalInterface
interface Message{
void chat();
}
public class Test {
public static void main(String[] args) {
// 接口不能实例化
// 匿名内部类创建实例化对象
Message msg=new Message() {
@Override
public void chat() {
System.out.println("匿名内部类实现的message聊天");
}
};
//Lambda表达式
Message msg1=()-> System.out.println("Lambda实现的message聊天");
msg.chat();
msg1.chat();
}
}
- 1.1.2
如果抽象方法参数只有一个,参数列表的括号可以省略
注意:同一作用域下,参数列表中的参数名不能和其他变量名冲突
package com.qqycc.lambda1;
/**
* 抽象方法只有一个参数
* Author: qqy
*/
@FunctionalInterface
interface IMessage{
void print(String msg);
}
public class Test2 {
public static void main(String[] args) {
IMessage msg=new IMessage(){
@Override
public void print(String msg) {
System.out.println(msg);
}
};
//参数列表中的参数名不能和其他变量名冲突
IMessage msg1=m-> System.out.println(m+" bonsoir");
msg.print("hello"); //hello
msg1.print("bonjour"); //bonjour bonsoir
}
}
- 1.1.3
如果抽象方法实现中只有return一条语句,则return和大括号可以省略,直接使用语句的结果就是返回值。
package com.qqycc.lambda1;
/**
* 有return的Lambda
* Author: qqy
*/
@FunctionalInterface
interface IAdd {
int add(int x,int y);
}
public class Test {
public static void main(String[] args) {
IAdd add=new IAdd() {
@Override
public int add(int x, int y) {
return x+y;
}
};
//函数式编程
IAdd add1=(x, y)-> x+y+10;
System.out.println(add.add(10,20)); //30
System.out.println(add1.add(10,20)); //40
}
}
- 1.1.4
标准写法(不简写):
接口名 变量名=(参数列表)->{
具体的方法体实现
[return 语句;]
};
package com.qqycc.lambda1;
/**
* 标准写法的Lambda
* Author: qqy
*/
@FunctionalInterface
interface IAdd{
int add(int x,int y);
}
public class Test1 {
public static void main(String[] args) {
IAdd add=new IAdd(){
@Override
public int add(int x, int y) {
int result=x+y;
result+=5;
return result;
}
};
IAdd add1= (x, y) -> {
int result=x+y;
result+=10;
return result;
};
System.out.println(add.add(10,20)); //35
System.out.println(add1.add(10,20)); //40
}
}
2.方法引用-与Lambda表达式搭配使用
给现有方法起一个别名
-
2.1 引用静态方法
类名称 :: 静态方法名称;
package com.qqycc;
/**
* 引用静态方法
* Author: qqy
*/
interface IUtil<P,R>{ //泛型
R switchPara(P p); //P类型—>R类型
}
public class Test {
public static void main(String[] args) {
//接口对象覆写抽象方法,该抽象方法的实现照用String的valueOf方法
IUtil<Integer,String> util=String :: valueOf;
//相当于调用String.valueOf(10);
System.out.println(util.switchPara(10));
System.out.println(Integer.valueOf(10));
}
}
-
2.2 引用对象方法
实例化对象 :: 普通方法;
package com.qqycc;
/**
* 引用对象方法
* Author: qqy
*/
interface IUtil1<R>{ //泛型
R switchPara(); //P类型—>R类型
}
public class Test1 {
public static void main(String[] args) {
IUtil1<String> util="hello"::toUpperCase;
//相当于调用"hello".toUpperCase();
System.out.println(util.switchPara());
System.out.println("hello".toUpperCase());
}
}
-
2.3 引用类中普通方法
类名称 :: 普通方法;
package com.qqycc;
/**
* 引用类中普通方法
* Author: qqy
*/
interface IUtil2<R,P>{
R compare(P p1,P p2);
}
public class Test2 {
public static void main(String[] args) {
IUtil2<Integer,String>util=String::compareTo;
//相当于调用String.compareTo();
System.out.println(util.compare("1","2"));
System.out.println("1".compareTo("2"));
}
}
-
2.4 引用构造方法
类名称 :: new
package com.qqycc;
/**
* 引用构造方法
* Author: qqy
*/
class Person{
private String name;
private Integer age;
public Person(String name,Integer age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "Person{"+"name="+this.name+"age="+this.age+"}";
}
}
interface IUti3<R,PN,PR>{
R createPer(PN p1,PR p2);
}
public class Test3 {
public static void main(String[] args) {
IUti3<Person,String,Integer>util=Person::new;
//相当于调用了Person的new Person();
System.out.println(util.createPer("张三",45));
Person per=new Person("张三",45);
System.out.println(per);
}
}
3.内建函数式接口
Lamdba的核心——函数式接口。
函数式接口的核心——只有一个抽象方法。
- 函数式编程分为以下四种接口:
-
3.1 功能型函数式接口
根据一个入参,返回一个结果。
public interface Function<T, R> R apply(T t);
package com.qqycc.bulidin;
import java.util.function.Function;
import java.util.function.IntFunction;
/**
* 功能型函数接口
* Author: qqy
*/
public class Test {
public static void main(String[] args) {
Function<Object, String> function = (value) -> {
return value.toString();
};
String str = function.apply("Bonjour");
System.out.println(str);
//参数确定,返回值不确定
IntFunction intFunction=String::valueOf;
System.out.println(intFunction.apply(100));
}
}
-
3.2 供给型函数式接口
通过函数调用,返回一个对象
public interface Supplier T get();
package com.qqycc.bulidin;
import java.util.function.Supplier;
/**
* 供给型函数接口
* Author: qqy
*/
class Person{
public String name;
public int age;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "Person{name="+this.name+"age="+this.age+"}";
}
}
public class Test1 {
public static void main(String[] args) {
Supplier<Person> supplier=()->{
return new Person("Mary", 18);
};
System.out.println(supplier.get());
Supplier<String>supplier1="Hello"::toUpperCase;
System.out.println(supplier1.get());
}
}
-
功能型+供给型结合使用
package com.qqycc.bulidin;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 功能型+供给型
* Author: qqy
*/
class Person1{
public String name;
public int age;
public Person1(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "Person{name="+this.name+"age="+this.age+"}";
}
}
public class Test2 {
public static void main(String[] args) {
//y=f(x) x->Supplier,y->String
Function<Supplier<Person>, String> function=(s)->{
return s.get().toString();
};
//x=g() (),x->Person
Supplier<Person> s=()->{
return new Person("Mary",18);
};
String res=function.apply(s);
System.out.println(res);
}
}
-
3.3 消费型函数式接口
有参数,没有返回值
public interface Consumer void accept(T t);
package com.qqycc.bulidin;
import java.util.function.Consumer;
/**
* 消费型函数式接口
* Author: qqy
*/
public class Test3 {
public static void main(String[] args) {
Consumer<String> consumer=(str)->{
System.out.println(str);
};
consumer.accept("Hello");
Consumer<String[]> consumer1=(strs)->{
for(String item:strs){
System.out.println(item);
}
};
consumer1.accept(new String[]{"v","i","e"});
Consumer<String> consumer2=System.out::println; //引用对象方法 out是一个对象
consumer2.accept("C'est la vie");
}
}
-
3.4 断言型接口
传入参数,返回值为boolean类型
public interface Predicate boolean test(T t);
package com.qqycc.bulidin;
import java.util.function.Predicate;
/**
* Author: qqy
*/
class Person2{
public String name;
public int age;
public Person2(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "Person{name="+this.name+"age="+this.age+"}";
}
}
public class Test4 {
public static void main(String[] args) {
Predicate<String> predicate="Hello"::endsWith;
//等价于"Hello".endsWith
boolean res=predicate.test("o");
System.out.println(res); //true
//参数 Object类型,判断——若参数对象是由Person类实例化的,返回true,否则返回false
Predicate<Object> predicate1=(obj)->{
return obj instanceof Person2;
};
System.out.println(predicate1.test("Hello")); //false
System.out.println(predicate1.test(new Person2("Lila",20))); //true
predicate1="String"::equals;
System.out.println(predicate1.equals("String")); //false
}
}