我是靠谱客的博主 阳光大船,最近开发中收集的这篇文章主要介绍java 箭头函数_Java8的Lambda表达式(箭头函数),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

函数式编程思想

在数学中 函数就是有输入量和输出量的一套计算方案 也就是“拿什么东西做什么事情”

相对而言 面向对象过分强调必须通过对象的形式来做事情

而函数式思想则尽量忽略面向对象的复杂语法——强调做什么 而不是以什么形式做

面向对象的思想:

做一件事情 找一个能解决这个事情的对象 调用对象的方法 完成事情

函数式编程思想:

只要能获取到结果 谁去做的 怎么做的都不重要,重视的是结果 不重视过程

可能不太好理解 我们举个简单的栗子:

代码冗余

public static void main(String[] args) {

RunnableImpl runnable=new RunnableImpl();

Thread thread=new Thread(runnable);

thread.start();

// 使用匿名内部类简化

Runnable runnable1 = new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " - new");

}

};

new Thread(runnable1).start();

// 继续简化

new Thread(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " - new");

}

}).start();

}

在这段多线程代码中:

1、Thread 类需要 Runnable 接口作为参数 因为其中的抽象 run 方法是用来指定线程任务内容的核心

2、为了指定 run 的方法体 不得不需要存在一个Runnable接口的实现类

3、为了省去定义一个RunnableImpl实现类的麻烦 不得不使用匿名内部类

4、因为必须覆盖重写抽象的run方法 所以方法名称 方法参数和方法返回值都不得不再写一遍 且不能写错

而实际上 只有方法体才是关键所在

因此 我们需要转换我们的编程思想

更加关注做什么 而不是怎么做

我们为了做这件事情而不得不创建一个匿名内部类对象

而我们真正希望做的事情是将 run 方法体内的代码传递给 Thread 类

传递一段代码——这才是真正的目的

更加简便:

在2014年3月Oracle所发布的Java 8(JDK 1.8)中 加入了Lambda表达式的重量级新特性 打开了新世界的大门

如下案例:

public static void main(String[] args) {

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

new Thread(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " - new");

}

}).start();

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

new Thread(() -> {

System.out.println(Thread.currentThread().getName() + " - new");

}

).start();

}

我们来详细看一下:

Runnable 接口只有一个 run 方法的定义:public abstract void run()

即制定了一种做事情的方案(其实就是一个函数):

无参数:不需要任何条件即可执行该方案

无返回值:该方案不产生任何结果

代码块(方法体):该方案的具体执行步骤

在Lambda表达式中更为简单:() ‐> System.out.println("方法执行")

前面的一对小括号即 run 方法的参数(无) 代表不需要任何条件

中间的一个箭头代表将前面的参数传递给后面的代码

后面的输出语句即业务逻辑代码

一、Lambda表达式的标准格式

Lambda省去了面向对象语法的条条框框

格式由3个部分组成:

一些参数

一个箭头

一段代码

标准格式:

(参数类型 参数名称) ‐> { 代码语句 }

小括号内的语法与传统方法参数列表一致:无参数则留空 多个参数则用逗号分隔

-> 是新引入的语法格式 代表指向动作

大括号内的语法与传统方法体要求基本一致

二、案例:

1、无参数无返回值

接口类:

public interface Cook {

public abstract void makeFood();

}

测试类:

public class CookTest {

public static void main(String[] args) {

// 调用invokeCook()方法 传递Cook接口的匿名内部类对象

invokeCook(new Cook() {

@Override

public void makeFood() {

System.out.println("开饭了");

}

});

// 使用Lambda表达式简化匿名内部类的书写

invokeCook(() -> {

System.out.println("开饭了");

});

}

// 定义一个方法 参数传递Cook接口 方法内部调用Cook接口中的makeFood()方法

public static void invokeCook(Cook cook)

{

cook.makeFood();

}

}

2、有参数有返回值

例一、

实体类:

public class Person {

private String name;

private int age;

...

}

测试类:

public class ArraysTest {

public static void main(String[] args) {

// 使用数组存储多个Person对象

Person[] arr={new Person("小A",10),

new Person("小B",13),

new Person("小C",12)};

// 升序操作

Arrays.sort(arr, new Comparator() {

@Override

public int compare(Person o1, Person o2) {

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

}

});

// 使用Lambda表达式简化匿名内部类的书写

Arrays.sort(arr,(Person o1, Person o2) -> {

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

});

// 遍历输出结果

for (Person p:arr)

{

System.out.println(p);

}

}

}

例二、

计算类:

public interface Calculate {

public abstract int calc(int a,int b);

}

测试类:

public class CalculateTest {

public static void main(String[] args) {

// 调用方法 参数是一个接口 可以使用匿名内部类

invokeCalc(1, 2, new Calculate() {

@Override

public int calc(int a, int b) {

return a+b;

}

});

// 使用Lambda表达式简化匿名内部类的书写

invokeCalc(1,2,(int a,int b) -> {

return a+b;

});

}

// 参数传递两个int类型的整数和Calculate接口 内部调用方法计算两个整数的和

public static void invokeCalc(int a,int b,Calculate calculate)

{

System.out.println(calculate.calc(a, b));

}

}

三、Lambda省略格式

Lambda表达式是可推导可省略的

凡是根据上下文推导出来的内容 都可以省略书写

可省略的内容:

1、参数列表:括号中参数列表的数据类型可以省略不写 因为在接口里已经定义了类型

2、参数列表:括号中的参数如果只有一个 那么类型和()都可以省略

3、代码:如果{}中的代码只有一行 那么无论是否有返回值 都可以省略{}和return和分号 但要省略必须一起省略

public static void main(String[] args) {

// 在JDK1.7版本之前 必须把前后的泛型都写上

ArrayList arrayList1=new ArrayList();

// 在JDK1.7版本之后 等号后的泛型可省略 因为可以根据前面的泛型推导出来

ArrayList arrayList2=new ArrayList<>();

}

案例

无参数无返回值:

// 调用invokeCook()方法 传递Cook接口的匿名内部类对象

invokeCook(new Cook() {

@Override

public void makeFood() {

System.out.println("开饭了");

}

});

// 使用Lambda表达式简化匿名内部类的书写

invokeCook(() -> {

System.out.println("吃饭了");

});

// 优化省略Lambda ★

invokeCook(() -> System.out.println("吃饭了"));

有参数有返回值:

// 调用方法 参数是一个接口 可以使用匿名内部类

invokeCalc(1, 2, new Calculate() {

@Override

public int calc(int a, int b) {

return a+b;

}

});

// 使用Lambda表达式简化匿名内部类的书写

invokeCalc(1,2,(int a,int b) -> {

return a+b;

});

// 优化省略Lambda ★

invokeCalc(1,2,(a,b) -> a+b);

总结:

1、使用Lambda必须具有接口 且要求接口中有且仅有一个抽象方法

因此 无论是JDK内置的 Runnable 接口或 Comparator 接口还是自定义的接口 只有当接口中的抽象方法存在且唯一时 才可使用Lambda

因为如果有多个抽象方法的话 就不知道调用哪个抽象方法了

2、使用Lambda必须具有上下文推断

也就是方法的参数或局部变量类型必须为Lambda对应的接口类型 才能使用Lambda作为该接口的实例

注:有且仅有一个抽象方法的接口称为函数式接口

最后

以上就是阳光大船为你收集整理的java 箭头函数_Java8的Lambda表达式(箭头函数)的全部内容,希望文章能够帮你解决java 箭头函数_Java8的Lambda表达式(箭头函数)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部