Java Lambda 表达式(java lambda 表达式原理)

  本篇文章为你整理了Java Lambda 表达式(java lambda 表达式原理)的详细内容,包含有javalambda表达式用法 java lambda 表达式原理 java lambda 表达式生成类 java lambda 表达式 比较日期 Java Lambda 表达式,希望能帮助你了解 Java Lambda 表达式。

   Java Lambda 表达式

   Java 8 新特性

  Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。

  Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

  使用 Lambda 表达式可以使代码变的更加简洁紧凑。

  lambda 表达式的语法格式如下:

  
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)

  (String s) - System.out.print(s)

 

 

  在 Java8Tester.java 文件输入以下代码:

  Java8Tester.java 文件

  public class Java8Tester {

   public static void main(String args[]){

   Java8Tester tester = new Java8Tester();

   // 类型声明

   MathOperation addition = (int a, int b) - a + b;

   // 不用类型声明

   MathOperation subtraction = (a, b) - a - b;

   // 大括号中的返回语句

   MathOperation multiplication = (int a, int b) - { return a * b; };

   // 没有大括号及返回语句

   MathOperation division = (int a, int b) - a / b;

   System.out.println( 10 + 5 = + tester.operate(10, 5, addition));

   System.out.println( 10 - 5 = + tester.operate(10, 5, subtraction));

   System.out.println( 10 x 5 = + tester.operate(10, 5, multiplication));

   System.out.println( 10 / 5 = + tester.operate(10, 5, division));

   // 不用括号

   GreetingService greetService1 = message -

   System.out.println( Hello + message);

   // 用括号

   GreetingService greetService2 = (message) -

   System.out.println( Hello + message);

   greetService1.sayMessage( Runoob );

   greetService2.sayMessage( Google );

   interface MathOperation {

   int operation(int a, int b);

   interface GreetingService {

   void sayMessage(String message);

   private int operate(int a, int b, MathOperation mathOperation){

   return mathOperation.operation(a, b);

  
Lambda 表达式主要用来定义行内执行的方法类型接口(例如,一个简单方法接口)。在上面例子中,我们使用各种类型的 Lambda 表达式来定义 MathOperation 接口的方法,然后我们定义了 operation 的执行。

  Lambda 表达式免去了使用匿名方法的麻烦,并且给予 Java 简单但是强大的函数化的编程能力。

  
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

  在 Java8Tester.java 文件输入以下代码:

  Java8Tester.java 文件

  public class Java8Tester {

   final static String salutation = Hello! ;

   public static void main(String args[]){

   GreetingService greetService1 = message -

   System.out.println(salutation + message);

   greetService1.sayMessage( Runoob );

   interface GreetingService {

   void sayMessage(String message);

  
final int num = 1;

   Converter Integer, String s = (param) - System.out.println(String.valueOf(param + num));

   s.convert(2); // 输出结果为 3

   public interface Converter T1, T2 {

   void convert(int i);

  
lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

  

int num = 1; 

 

  Converter Integer, String s = (param) - System.out.println(String.valueOf(param + num));

  s.convert(2);

  num = 5;

  //报错信息:Local variable num defined in an enclosing scope must be final or effectively

   final

 

  在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

  

String first = ""; 

 

  Comparator String comparator = (first, second) - Integer.compare(first.length(), second.length()); //编译会出错

 

   Java 8 新特性

  
#0彬

  117***8834@qq.com

   27

System.out.println("10 + 5 = " + tester.operate(10, 5, addition));

 

  这里还有另外一种写法

  

System.out.println("10+5=" + addition.operation(10, 5));

 

  
此接口要求必须是函数式接口,如果其中有两个方法则lambda表达式会编译错误。但java8的新特性如许实现如下写法:

  
}

 
彬彬

 

  117***8834@qq.com

  5年前 (2017-12-02)

  #0Looo

  252***56432@qq.com

   参考地址

   52lambdas 实现 Runnable 接口

  下面是使用 lambdas 来实现 Runnable 接口的示例:

  

// 1.1使用匿名内部类 

 

  new Thread(new Runnable() {

   @Override

   public void run() {

   System.out.println("Hello world !");

  }).start();

  // 1.2使用 lambda expression

  new Thread(() - System.out.println("Hello world !")).start();

  // 2.1使用匿名内部类

  Runnable race1 = new Runnable() {

   @Override

   public void run() {

   System.out.println("Hello world !");

  // 2.2使用 lambda expression

  Runnable race2 = () - System.out.println("Hello world !");

  // 直接调用 run 方法(没开新线程哦!)

  race1.run();

  race2.run();

 

  Runnable 的 lambda 表达式,使用块格式,将五行代码转换成单行语句。 接下来,在下一节中我们将使用 lambdas 对集合进行排序。

  使用 Lambdas 排序集合

  在 Java 中,Comparator 类被用来排序集合。 在下面的例子中,我们将根据球员的 name、surname、name 长度以及最后一个字母。 和前面的示例一样,先使用匿名内部类来排序,然后再使用 lambda 表达式精简我们的代码。

  在第一个例子中,我们将根据name来排序list。 使用旧的方式,代码如下所示:

  

String[] players = {"Rafael Nadal", "Novak Djokovic", 

 

   "Stanislas Wawrinka", "David Ferrer",

   "Roger Federer", "Andy Murray",

   "Tomas Berdych", "Juan Martin Del Potro",

   "Richard Gasquet", "John Isner"};

  // 1.1 使用匿名内部类根据 name 排序 players

  Arrays.sort(players, new Comparator String () {

   @Override

   public int compare(String s1, String s2) {

   return (s1.compareTo(s2));

  });

 

  使用 lambdas,可以通过下面的代码实现同样的功能:

  

// 1.2 使用 lambda expression 排序 players 

 

  Comparator String sortByName = (String s1, String s2) - (s1.compareTo(s2));

  Arrays.sort(players, sortByName);

  // 1.3 也可以采用如下形式:

  Arrays.sort(players, (String s1, String s2) - (s1.compareTo(s2)));

  其他的排序如下所示。 和上面的示例一样,代码分别通过匿名内部类和一些lambda表达式来实现Comparator :

  // 1.1 使用匿名内部类根据 surname 排序 players

  Arrays.sort(players, new Comparator String () {

   @Override

   public int compare(String s1, String s2) {

   return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));

  // 1.2 使用 lambda expression 排序,根据 surname

  Comparator String sortBySurname = (String s1, String s2) -

   ( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );

  Arrays.sort(players, sortBySurname);

  // 1.3 或者这样,怀疑原作者是不是想错了,括号好多...

  Arrays.sort(players, (String s1, String s2) -

   ( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) )

  // 2.1 使用匿名内部类根据 name lenght 排序 players

  Arrays.sort(players, new Comparator String () {

   @Override

   public int compare(String s1, String s2) {

   return (s1.length() - s2.length());

  // 2.2 使用 lambda expression 排序,根据 name lenght

  Comparator String sortByNameLenght = (String s1, String s2) - (s1.length() - s2.length());

  Arrays.sort(players, sortByNameLenght);

  // 2.3 or this

  Arrays.sort(players, (String s1, String s2) - (s1.length() - s2.length()));

  // 3.1 使用匿名内部类排序 players, 根据最后一个字母

  Arrays.sort(players, new Comparator String () {

   @Override

   public int compare(String s1, String s2) {

   return (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));

  // 3.2 使用 lambda expression 排序,根据最后一个字母

  Comparator String sortByLastLetter =

   (String s1, String s2) -

   (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));

  Arrays.sort(players, sortByLastLetter);

  // 3.3 or this

  Arrays.sort(players, (String s1, String s2) - (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));

LoooLooo

 

  252***56432@qq.com

   参考地址

  5年前 (2018-09-03)

  #0天命风流

  lic***geek@163.com

   9参考实例:

  

public class Test2 {

 

   public static void main(String[] args) {

   Test2 tester = new Test2();

   tester.testOperation();

   public void testOperation() {

   * 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)

   * 6.接收2个参数(数字类型),第1个数字加1,第2个数字加2,再求积

   * (int x, int y) - { x += 1; y += 2; return x * y }

   * MathOperation接口有且只有一个抽象方法operation时,

   * 可以使用 MathOperation addition = (int a, int b) - a + b;

   * addition为实现了接口的一个对象,

   * (int a, int b) - a + b;作为一个函数实现了MathOperation的抽象方法operation;

   * 当MathOperation接口存在两个抽象方法时;

   * MathOperation addition = (int a, int b) - a + b;在编写时报错;

   // 传入的参数带有类型声明

   MathOperation addition = (int a, int b) - a + b;

   // 不用带类型声明

   MathOperation subtraction = (a, b) - a = b;

   // 大括号中带返回语句

   MathOperation multiplication = (int a, int b) - {

   return a * b;

   // 没有带大括号及返回语句

   MathOperation division = (int a, int b) - a / b;

   System.out.println("2 * 3 = " + operate(2, 3, multiplication));

   System.out.println("6 / 3 = " + operate(6, 3, (int a, int b) - a / b));

   // 输出结果,无返回值

   GreetingService greetService = (String message) -

   System.out.println("hello " + message);

   greetService.sayMessage("world");

   interface MathOperation {

   int operation(int a, int b);

   // int operation2(int a, int b);

   default int operation3(int a, int b) {

   return a + b;

   interface GreetingService {

   void sayMessage(String message);

   private int operate(int a, int b, MathOperation mathOperation) {

   return mathOperation.operation(a, b);

  }

天命风流天命风流

 

  lic***geek@163.com

  4年前 (2018-12-05)

  #0Yyyyyp

  810***893@qq.coom

   参考地址

   5使用 Lambda 表达式对中文排序:

  
public static void main(String[] args) {

   List String list = Arrays.asList("谷歌", "腾讯", "百度", "淘宝");

   Collator collator = Collator.getInstance(Locale.CHINA);

   list.sort((string1, string2) - collator.compare(string1, string2));

   System.out.println(list);

  }

 
YyyyypYyyyyp

 

  810***893@qq.coom

   参考地址

  4年前 (2019-05-17)

  #0奋斗的小猿

  157***09440@163.com

   7以下实例反映出 lambda 不一定需要 final 关键字才可以访问外部变量。

  

public class LambdaTest {

 

   final static String hello = "Hello, ";

   private static String goodbye = "Goodbye, ";

   public static void main(String[] args) {

   GreetingMessage message1 = (String message) -

   System.out.println(hello + message);

   GreetingMessage message2 = (message) -

   //goodbye = "the time is late, Id go now, goodbye";

   goodbye += "the time is late, Id go now, ";

   System.out.println(goodbye + message);

   message1.sayMessage("张三");

   message2.sayMessage("李四");

   interface GreetingMessage {

   void sayMessage(String message);

  }

 

  运行程序后,结果 :

  

Hello, 张三

 

  Goodbye, the time is late, Id go now, 李四

 

  奋斗的小猿奋斗的小猿

  157***09440@163.com

  4年前 (2019-07-24)

  #0ByVie

  635***000@qq.com

   39Lambda

  匿名内部类的格式:

  

new 父类或接口() {​

 

   重写的方法;​

  }

 

  在匿名内部类中,有很多内容都是冗余的。

  比如在使用匿名内部类实现多线程的代码中。

  因为 Thread 构造方法中需要传递 Runnable 接口类型的参数,所以我们不得不 new Runnable。

  因为要重写 Runnable 中的 run 方法,所以不得不写了public void run。

  整个匿名内部类中最关键的东西是方法,方法中最关键的有前中后三点。

  前:参数。

  中:方法体

  后:返回值

  最好的情况是只关注匿名内部类中最核心的这些内容(方法参数,方法体,返回值)如果使用Lambda表达式,可以只关注最核心的内容,Lambda 表达式是匿名内部类的简化写法。

  Lambda 属于函数式编程思想。

  面向对象思想:怎么做。

  函数式编程思想:做什么。

  

public class Demo01Inner {

 

   public static void main(String[] args) {

   //使用匿名内部类的方式实现多线程。

   new Thread(new Runnable() {

   @Override

   public void run() {

   System.out.println(Thread.currentThread().getName() + "执行了");

   }).start();

   //使用Lambda表达式实现多线程

   new Thread(() - System.out.println(Thread.currentThread().getName() + "执行了")).start();

  }

 

  匿名内部类可以省去单独创建 .java 文件的操作。但是匿名内部类也是有缺点的,写法太冗余了,里面有很多多余的部分。

  匿名内部类也有简化写法,匿名内部类的简化写法是 Lambda 表达式匿名内部类中最关键的内容是方法的参数,方法体,以及返回值,而在 Lambda 表达式中,关注的就是这三个关键的东西。

  Lambda 表达式的标准格式:

  

(参数类型 参数名) - {

 

   方法体;

   return 返回值;

  }

 

  格式解释:

  小括号中的参数和之前方法的参数写法一样,可以写任意个参数,如果多个参数,要使用逗号隔开。

  - 是一个运算符,表示指向性动作。

  大括号中的方法体以及 return 返回值的写法和之前方法的大括号中的写法一样。

  Lambda 表达式是函数式编程思想。

  函数式编程:可推导,就是可省略。

  因为在 Thread 构造方法中需要 Runnable 类型的参数,所以可以省略 new Runnable。

  因为 Runnable 中的只有一个抽象方法 run,所以重写的必然是这个 run 方法,所以可以省略 run 方法的声明部分(public void run)

  Lambda 表达式可以省略面向对象中的一些条条框框,让我们只关注最核心的内容。

  

public class Demo02Lambda {

 

   public static void main(String[] args) {

   //实现多线程(单独创建.java)

   new Thread(new Task()).start();

   //使用匿名内部类的方式实现多线程

   new Thread(new Runnable() {

   @Override

   public void run() {

   System.out.println(Thread.currentThread().getName() + "执行了");

   }).start();

   //使用Lambda表达式完成多线程

   new Thread(() - {

   System.out.println(Thread.currentThread().getName() + "执行了");

   }).start();

  }

 

  匿名内部类与 Lambda 函数比较

  

public class Demo03Collections {

 

   public static void main(String[] args) {

   //创建集合

   List Student list = new ArrayList ();

   //添加元素

   list.add(new Student("嫐", 20));

   list.add(new Student("嬲", 18));

   list.add(new Student("挊", 22));

   //使用比较器排序对集合中的学生对象根据年龄升序排序

   //Collections.sort(list, new Rule());

   //使用匿名内部类

   Collections.sort(list, new Comparator Student () {

   @Override

   public int compare(Student o1, Student o2) {

   return o1.getAge() - o2.getAge();

   //使用Lambda表达式

   Collections.sort(list, (Student o1, Student o2) - {

   return o1.getAge() - o2.getAge();

   Collections.sort(list, (o1, o2) - o1.getAge() - o2.getAge());

   System.out.println(list);

  }

 

  Lambda 格式

  Lambda 表达式的标准格式:

  

(参数类型 参数名) - {

 

   方法体;

   return 返回值;

  }

 

  Lambda 表达式的省略规则:

  1. 小括号中的参数类型可以省略。

  2. 如果小括号中只有一个参数,那么可以省略小括号。

  3. 如果大括号中只有一条语句,那么可以省略大括号,return,分号。

  

public class Demo04SimpleLambda {

 

   //定义方法,使用接口当做参数

   public static void method(MyInterface m) {

   m.printStr("hello");

   public static void main(String[] args) {

   //调用method方法,参数传递MyInterface实现类对象

   method(new MyInterface() {

   @Override

   public void printStr(String str) {

   System.out.println(str);

   //使用Lambda表达式的标准格式。

   method((String str) - {

   System.out.println(str);

   //1. 小括号中的参数类型可以省略。

   method((str) - {

   System.out.println(str);

   //2. 如果小括号中只有一个参数,那么可以省略小括号。

   method(str - {

   System.out.println(str);

   //3. 如果大括号中只有一条语句,那么可以省略大括号,return,分号。

   method(str - System.out.println(str));

  }

 

  Lambda 使用条件

  Lambda 表达式的使用前提:

  必须有接口(不能是抽象类),接口中有且仅有一个需要被重写的抽象方法。

  必须支持上下文推导,要能够推导出来 Lambda 表达式表示的是哪个接口中的内容。

  可以使用接口当做参数,然后传递 Lambda 表达式(常用),也可以将 Lambda 表达式赋值给一个接口类型的变量。

  

public class Demo05BeforeLambda {

 

   //使用接口当做参数

   public static void method(MyInterface m) {//m = s - System.out.println(s)

   m.printStr("HELLO");

   public static void main(String[] args) {

   //使用接口当做参数,然后传递Lambda表达式。

   //method(s - System.out.println(s));

   //使用匿名内部类方式创建对象

   MyInterface m = new MyInterface() {

   @Override

   public void printStr(String str) {

   System.out.println(str);

   MyInterface m = str - System.out.println(str);

   m.printStr("Hello");

  }

ByVieByVie

 

  635***000@qq.com

  4年前 (2019-08-17)

  #0穹的小叮当

  wdl***58111027@163.com

   6测试实例:

  

public class LambdaDemo {

 

   final static String ST = "Hello!";

   String ss = "Hello!";

   public static void main(String[] args) {

   int c = 8;

   int d = 4;

   // int a = 10; 不允许声明一个与局部变量同名的参数或者局部变量。

   AddService add = (a, b) - a + b;

   System.out.println(c + " + " + d + " = " + add.operation(c, d));

   add = (a, b) - a - b;

   System.out.println(c + " - " + d + " = " + add.operation(c, d));

   add = (a, b) - a * b;

   System.out.println(c + " * " + d + " = " + add.operation(c, d));

   add = (a, b) - a / b;

   System.out.println(c + " / " + d + " = " + add.operation(c, d));

   add = (int a, int b) - {

   return a + b;

   System.out.println(c + " + " + d + " = " + add.operation(c, d));

   // 打印方法中可以获取ST,c,d 但是获取不到ss (且c,d不可更改,隐性的具有 final 的语义)

   GreetingService gs = str - System.out.println(ST + str);

   gs.operation(String.valueOf(c));

   * 实现方法可自定义

   interface AddService {

   Integer operation(int a, int b);

   interface GreetingService {

   void operation(String str);

  }

穹的小叮当穹的小叮当

 

  wdl***58111027@163.com

  4年前 (2019-09-28)

  以上就是Java Lambda 表达式(java lambda 表达式原理)的详细内容,想要了解更多 Java Lambda 表达式的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: