Java 8 lamda表达式

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

前些日子在看Spring cloud gateway源码时,常看到lamda表达式。由于自己对lamda表达式不是很熟悉,特此重新学习。

前言

Lambda 表达式是 Java 8 发布的最重要新特性。它允许把函数作为一个方法的参数,传递进方法中去。使用 Lambda 表达式可以使代码变的更加简洁紧凑。需要注意的是lamda表达式的使用依赖于函数式接口。

为什么要使用lamda表达式

目前来说,使用lamda表达式最突出的优点在于简化代码,使代码变的更加简洁紧凑。

以最常见的线程创建为例:

  1. 传统方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码public class Test {
   public static void main(String[] args) {
       Thread thread = new Thread(new RunTest());
       thread.run();
  }
}


class RunTest implements Runnable{

   @Override
   public void run() {
       System.out.println(123);
  }
}
  1. 普通匿名内部类的方式
1
2
3
4
5
6
7
8
9
10
11
java复制代码public class Test {
   public static void main(String[] args) {
       Thread thread = new Thread(new Runnable() {
           @Override
           public void run() {
               System.out.println("123");
          }
      });
       thread.run();
  }
}
  1. lamda表达式方式
1
2
3
4
5
6
7
8
9
java复制代码public class Test {

   public static void main(String[] args) {
       Thread thread = new Thread(() -> {
           System.out.println(123);
      });
       thread.run();
  }
}

通过比较可以发现,使用lamda表达式的方式代码更为简洁。

相关概念

lamda表达式格式

lamda表达式一般由以下格式构成:

1
2
3
java复制代码(parameters) -> expression

(parameters) ->{ statements; }

具体见以下示例

1
2
3
4
5
java复制代码()->5; // 无参数,返回5

(int x,int y)->5*x+6*y; // 多参数,返回5*x+6*y的结果

x->5*x // 单参数,返回5*x的结果。当只有一个参数时,可以忽略括号和参数类型

函数式接口

lamda表达式的使用依赖于函数式接口。所谓函数式接口,是指任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。

代码示例如下所示:

1
2
3
4
java复制代码@FunctionalInterface
public interface TestInterface {
   int test(int x);
}

其中,为了避免后来人给这个接口添加函数后,导致该接口有多个函数,不再是函数式接口,我们可以在接口类的上方声明 @FunctionalInterface

用lamda实现函数式接口的方式如下:

1
2
3
4
5
6
7
8
9
10
11
java复制代码public class Test {
   public static void main(String[] args) throws Exception {
       TestInterface test;
       test = x->{
           System.out.println(5*x);
           return 5*x;
      };
       int num = test.test(6);
       System.out.println(num);
  }
}

由以上代码可见,对函数式接口赋值lamda语句,本质上是对接口方法进行实现。

方法引用

除了普通lamda表达式->类型外,还有另外一种写法,被称为方法引用

所谓方法引用,就是指如果一个方法的参数一致,返回值类型相同,那么就可以通过方法引用的方式对函数式接口进行赋值。

方法引用的格式如下:

1
2
java复制代码// 类名::方法名
Integer::parseInt

代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码public class Test {
   public static void main(String[] args) throws Exception {
       TestInterface testInterface;
       testInterface = Integer::parseInt;
       int test1 = testInterface.test("123");
       // 上述代码等价于以下代码
       testInterface = x -> {
           return Integer.parseInt(x);
      };
       int test2 = testInterface.test("123");
  }
}

除此之外,方法引用还有以下情况:

  • 构造器引用: 它的语法是Class::new,或者更一般的Class< T >::new实例如下:
1
2
java复制代码final Car car = Car.create( Car::new ); 
final List< Car > cars = Arrays.asList( car );
  • 静态方法引用: 它的语法是Class::static_method,实例如下:
1
java复制代码cars.forEach( Car::collide );
  • 特定类的任意对象的方法引用: 它的语法是Class::method实例如下:
1
java复制代码cars.forEach( Car::repair );
  • 特定对象的方法引用: 它的语法是instance::method实例如下:
1
java复制代码final Car police = Car.create( Car::new ); cars.forEach( police::follow );

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%