1 什么是Lambda表达式
lambda源自数学上的概念,如果你感兴趣可以自行了解,下面说一下Java中的lambda表达式。
1.1 Java中Lambda表达式的格式
(type p1,type p2,...) -> {函数逻辑}
例子:
(String first, String second) ->
{
if(first.length() > second.length())
{
return 1;
}else if(first.length() < second.length()){
return -1;
}else
{
return 0;
}
}
1.2 Lambda表达式的注意事项与简化写法
- 如果lambda表达式没有入参,那么我们也要提供一个
空括号
,就像无参方法一样。
() ->{
for(int i = 1; i< 100; i++){
System.out.println(i);
}
}
- 一般我们可以省略入参的参数类型,编译器会自动推导出参数的类型
Comparator<String> comp = (k1,k2)->
{
return k1.length() - k2.length();
};
k1,k2的类型编译器会自动推导出是String类型
- 如果入参只有一个,我们可以省略括号
Function<String,String> fun1 = str -> {return str;};
- 如果lambda表达式的函数体只有一行代码,那么我们可以省略大括号,同时如果有返回值,return也可以一并去掉。
Function<String,String> fun1 = str -> str;
1.3 lambda表达式的使用
在Java中lambda表达式是和函数式接口绑定的,函数式接口简单理解就是只有一个抽象方法的接口。在jdk的java.util
包下提供了大量的函数式接口,其中有四个我们开发中常用的接口,按照规范,函数式接口一般使用注解@FunctionalInterface
来标识表明这个接口是一个函数式接口,下面是四个常用的函数式接口。
Function 函数式接口
例子
public static void testFun(){
Function<String,String> fun1 = str -> str;
System.out.println(fun1.apply("kobe"));
}
Predicate 函数式接口 (在判定是否的情况下可以使用,返回值是boolean值)
例子
public static void testPre(){
Predicate<String> pre = str -> str.isEmpty();
boolean flag = pre.test("");
System.out.println(flag);
}
Consumer 消费型接口,只有入参,没有返回值
例子
public static void testCon(){
Consumer<String> con = str-> System.out.println(str);
con.accept("hello world");
}
Supplier 供给型接口 没有入参,只有返回值
例子
public static void testSup(){
Supplier<String> sup = ()-> "就单纯返回一个字符串";
String s = sup.get();
System.out.println(s);
}
lambda表达式的函数引用
- 静态方法引用 直接类名::静态方法名
- 非静态方法引用 对象名::非静态方法名
/**
* 函数引用
*/
public class LambdaTest01 {
private static interface Calculate{
int calculate(int a, int b);
}
public static void main(String[] args) {
//Calculate calculate = (x,y) -> cal(x,y);
//静态函数引用 类::静态方法名
Calculate calculate = LambdaTest01::cal;
System.out.println(calculate.calculate(1,1));
//非静态函数调用,对象::非静态方法名
Calculate calculate1 = new LambdaTest01()::cal1;
System.out.println(calculate1.calculate(1,3));
}
private static int cal(int a, int b){
if (a<b){
return a-b;
}else if (a>b){
return b-a;
}
return a+b;
}
private int cal1(int a, int b){
if (a==b){
return a+b;
}
else {
return a-b;
}
}
}
lambda表达式的构造函数引用
public class LambdaTest02 {
private static class Person{
String name;
int age;
public Person(){
System.out.println("无参函数被调用了");
}
public Person(String name){
this.name = name;
System.out.println("有一个参数的构造方法被调用");
}
public Person(String name,int age){
this.name = name;
this.age = age;
System.out.println("有两个参数的构造方法被调用");
}
}
private interface GetPerson{
Person get();
}
private interface GetPersonBySingle{
Person get(String name);
}
private interface GetPersonByTwo{
Person get(String name,int age);
}
public static void main(String[] args) {
GetPerson getPerson = Person::new;
getPerson.get();
GetPersonBySingle getPersonBySingle = Person::new;
getPersonBySingle.get("科比");
GetPersonByTwo getPersonByTwo = Person::new;
getPersonByTwo.get("科比",10);
}
}
类方法的特殊引用
如果一个类的方法正好满足函数式接口的入参和返回值再加上对象本身作为参数匹配上 ,也可以直接类名::方法名来直接调用
public class LambdaTest03 {
private static class Person{
String name;
String getName(){
return this.name;
}
void setName(String name){
this.name = name;
}
}
private interface MyInterface{
String get(Person person);
}
private interface MyInferface1{
void set(Person person,String value);
}
public static void main(String[] args) {
//如果类中有一个方法正好满足lambda表达式的需求,可以直接用类::方法名来调用。
MyInterface myInterface = Person::getName;
Person person = new Person();
person.setName("kobe");
System.out.println(myInterface.get(person));
MyInferface1 myInferface1 = Person::setName;
Person person1 = new Person();
myInferface1.set(person1,"james");
System.out.println(person1.getName());
}
}
lambda表达式注意点
lambda表达式中如果使用了局部变量,那个无论这个局部变量有没有声明成常量,都会自动成为fianl常量。成员变量类变量则不影响。
public class LambdaTest04 {
private interface LambdaTest{
void test();
}
private interface LambdaTest01s{
void test(Integer num);
}
private static int y = 200;
public static void main(String[] args) {
//在lambda的代码块中,如果使用了一个局部变量,那么这个局部变量会自动被声明成final常量,不可改变。
//但是如果是成员变量就没有问题
int x = 10;
LambdaTest lambdaTest = ()->{
System.out.println("x = " + x);
System.out.println("y = " + y);
};
lambdaTest.test();
y = 300;
System.out.println("y = "+ y);
LambdaTest01s lambdaTest01s = (b) ->{
System.out.println(b);
};
for(Integer i=0; i< 10;i++){
lambdaTest01s.test(i);
}
}
}