Lambda表达式其实就是实现SAM接口的语法糖,作用就是简化代码的冗余,同时可读性也好过匿名内部类。

以下先一步步演示是如何把大段的代码变成一句代码的,加强理解!

第一种正常的写法

 1 public class Test {
2
3 public static void main(String[] args) {
4
5 //非Lambda表达式的方式创建一个线程
6 MyRunnable myRunnable = new MyRunnable();
7 Thread thread = new Thread(myRunnable);
8 thread.start();
9 }
10
11 }
12 class MyRunnable implements Runnable{
13
14 @Override
15 public void run() {
16 System.out.println("Hello Run");
17 }
18 }

结果:Hello Run

第二种匿名内部类

public class Test {

    public static void main(String[] args) {
//匿名内部类,带对象名字
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello Run");
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}

结果:Hello Run

第三种匿名内部类

public class Test {

    public static void main(String[] args) {
//匿名内部类,不带对象名
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Run");
}
});
thread.start();
}
}

结果:Hello Run

第四种匿名内部类

public class Test {

    public static void main(String[] args) {
//匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello Run");
}
}).start();
}
}

结果:Hello Run

第五种Lambda表达式

public class Test {

    public static void main(String[] args) {
//使用Lambda表达式
new Thread(() -> System.out.println("Hello Run")).start();
}
}

结果:Hello Run

以上的演变估计你已经大概知道这个是怎么演变过来的,那为什么这个Runnable可以这样只写呢?

原因就是Runnable符合接口SAM特征;   另外科普一下SAM:Single Abstract Method(一个抽象方法)

下面再来一个例子

import java.util.Arrays;

public class Test2 {

    public static void main(String[] args) {
//什么都不管,先来几辆车(代码中满足自己一下)
Car[] carArry = new Car[5];
carArry[0] = new Car(1, "BMW");
carArry[1] = new Car(2, "Mercedes-benz");
carArry[2] = new Car(3, "Audi");
carArry[3] = new Car(4, "Porsche");
carArry[4] = new Car(5, "Ferrari");
//这里就把我的豪车进行排序,按照id排序
Arrays.sort(carArry);
for (Car car : carArry) {
System.out.println(car);
}
} } class Car implements Comparable<Car> {
private int id;
private String brand; public Car(int id, String brand) {
this.id = id;
this.brand = brand;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} @Override
public String toString() {
return "Car{" +
"id=" + id +
", brand='" + brand + '\'' +
'}';
} @Override
public int compareTo(Car car) {
return this.id - car.id;
}
}

输出的结果:

Car{id=1, brand='BMW'}
Car{id=2, brand='Mercedes-benz'}
Car{id=3, brand='Audi'}
Car{id=4, brand='Porsche'}
Car{id=5, brand='Ferrari'}

这时候,为了秀一下我的车,我又想要按照品牌排序,这时候就要在实现一个类是按照品牌来排序的

import java.util.Arrays;
import java.util.Comparator; public class Test2 { public static void main(String[] args) {
//什么都不管,先来几辆车(代码中满足自己一下)
Car[] carArry = new Car[5];
carArry[0] = new Car(1, "BMW");
carArry[1] = new Car(2, "Mercedes-benz");
carArry[2] = new Car(3, "Audi");
carArry[3] = new Car(4, "Porsche");
carArry[4] = new Car(5, "Ferrari");
//这里就把我的豪车进行排序,按照id排序
Arrays.sort(carArry, new carByBrandComparator());
for (Car car : carArry) {
System.out.println(car);
}
} } /**
* 按汽车的品牌排序
**/
class carByBrandComparator implements Comparator<Car> { @Override
public int compare(Car brand1, Car brand2) {
return brand1.getBrand().compareTo(brand2.getBrand());
}
} class Car implements Comparable<Car> {
private int id;
private String brand; public Car(int id, String brand) {
this.id = id;
this.brand = brand;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} @Override
public String toString() {
return "Car{" +
"id=" + id +
", brand='" + brand + '\'' +
'}';
} @Override
public int compareTo(Car car) {
return this.id - car.id;
}
}

结果:

Car{id=3, brand='Audi'}
Car{id=1, brand='BMW'}
Car{id=5, brand='Ferrari'}
Car{id=2, brand='Mercedes-benz'}
Car{id=4, brand='Porsche'}

这时候排序就是按照品牌来排序了,可是这样就又多了一个类,是不是觉得很不爽,这就对了,因为还可以再简单一点,下面一起来看看:

我们采用匿名类来解决

import java.util.Arrays;
import java.util.Comparator; public class Test2 { public static void main(String[] args) {
//什么都不管,先来几辆车(代码中满足自己一下)
Car[] carArry = new Car[5];
carArry[0] = new Car(1, "BMW");
carArry[1] = new Car(2, "Mercedes-benz");
carArry[2] = new Car(3, "Audi");
carArry[3] = new Car(4, "Porsche");
carArry[4] = new Car(5, "Ferrari");
//这里就把我的豪车进行排序,按照id排序
Arrays.sort(carArry, new Comparator<Car>() {
@Override
public int compare(Car brand1, Car brand2) {
return brand1.getBrand().compareTo(brand2.getBrand());
}
});
for (Car car : carArry) {
System.out.println(car);
}
} } class Car implements Comparable<Car> {
private int id;
private String brand; public Car(int id, String brand) {
this.id = id;
this.brand = brand;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} @Override
public String toString() {
return "Car{" +
"id=" + id +
", brand='" + brand + '\'' +
'}';
} @Override
public int compareTo(Car car) {
return this.id - car.id;
}

结果:

Car{id=3, brand='Audi'}
Car{id=1, brand='BMW'}
Car{id=5, brand='Ferrari'}
Car{id=2, brand='Mercedes-benz'}
Car{id=4, brand='Porsche'}

甚至我们还可以更简单:

import java.util.Arrays;
import java.util.Comparator; public class Test2 { public static void main(String[] args) {
//什么都不管,先来几辆车(代码中满足自己一下)
Car[] carArry = new Car[5];
carArry[0] = new Car(1, "BMW");
carArry[1] = new Car(2, "Mercedes-benz");
carArry[2] = new Car(3, "Audi");
carArry[3] = new Car(4, "Porsche");
carArry[4] = new Car(5, "Ferrari");
//这里就把我的豪车进行排序,按照id排序
Arrays.sort(carArry, (brand1, brand2) -> brand1.getBrand().compareTo(brand2.getBrand()));
for (Car car : carArry) {
System.out.println(car);
}
} } class Car implements Comparable<Car> {
private int id;
private String brand; public Car(int id, String brand) {
this.id = id;
this.brand = brand;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} @Override
public String toString() {
return "Car{" +
"id=" + id +
", brand='" + brand + '\'' +
'}';
} @Override
public int compareTo(Car car) {
return this.id - car.id;
}
}

结果:

Car{id=3, brand='Audi'}
Car{id=1, brand='BMW'}
Car{id=5, brand='Ferrari'}
Car{id=2, brand='Mercedes-benz'}
Car{id=4, brand='Porsche'}

之所以可以这样写,也是因为Comparator符合SAM接口的特征;

到这里,是不是已经感受到Lambda的魅力!!!

这些函数式接口集中在java.util.function包中

可以分为四大类:

1、消费型接口:有参无返回值

2、供给型接口:无参有返回值

3、判断型接口:有参有返回值,但返回类型是boolean

4、功能型接口:有参有返回值

一、消费型接口
经典代表:
Consumer<T> 抽象方法 void accept(T t) 延伸代表:
(1)
BiConsumer<T,U> void accept(T t, U u) 接收两个对象用于完成功能
(2)
DoubleConsumer   void accept(double value) 接收一个double值
IntConsumer  void accept(int value) 接收一个int值
LongConsumer    void accept(long value) 接收一个long值
(3)
ObjDoubleConsumer<T> void accept(T t, double value) 接收一个对象和一个double值
ObjIntConsumer<T> void accept(T t, int value) 接收一个对象和一个int值
ObjLongConsumer<T> void accept(T t, long value) 接收一个对象和一个long值 总结:
(1)消费型接口,都以“Consumer”单词为结尾
(2)Bi开头,传两个参数 Binary(二元的)
(3)xxConsumer,前面的xx代表形参类型 二、供给型接口
经典代表:
Supplier<T> 抽象方法 T get() 延伸代表:
(1)BooleanSupplier boolean getAsBoolean() 返回一个boolean值
(2)DoubleSupplier double getAsDouble() 返回一个double值
(3)IntSupplier int getAsInt() 返回一个int值
(4)LongSupplier long getAsLong() 返回一个long值 总结:
(1)供给型接口以“Supplier”单词结尾
(2)xxSupplier说明返回xx类型的结果
(3)供给型接口的抽象方法都是无参的 三、判断型接口
经典代表:
Predicate<T> 抽象方法 boolean test(T t) 延伸代表:
(1)BiPredicate<T,U> boolean test(T t, U u) 接收两个对象
(2)DoublePredicate boolean test(double value) 接收一个double值
(3)IntPredicate boolean test(int value) 接收一个int值
(4)LongPredicate boolean test(long value) 接收一个long值 总结:
(1)判断型接口以“Predicate”结尾
(2)判断型接口抽象方法的返回值类型是固定的,是boolean
(3)xxPredicate,说明形参是xx类型的 四、功能型接口
经典代表:
Function<T,R> 抽象方法 R apply(T t) 延伸代表:
(1)
UnaryOperator<T> T apply(T t) 接收一个T类型对象,返回一个T类型对象结果
(2)
DoubleFunction<R> R apply(double value) 接收一个double值,返回一个R类型对象
IntFunction<R> R apply(int value) 接收一个int值,返回一个R类型对象
LongFunction<R> R apply(long value) 接收一个long值,返回一个R类型对象
(3)
ToDoubleFunction<T> double applyAsDouble(T value) 接收一个T类型对象,返回一个double
ToIntFunction<T> int applyAsInt(T value) 接收一个T类型对象,返回一个int
ToLongFunction<T> long applyAsLong(T value) 接收一个T类型对象,返回一个long
(4)
DoubleToIntFunction int applyAsInt(double value) 接收一个double值,返回一个int结果
DoubleToLongFunction long applyAsLong(double value) 接收一个double值,返回一个long结果
IntToDoubleFunction double applyAsDouble(int value) 接收一个int值,返回一个double结果
IntToLongFunction long applyAsLong(int value) 接收一个int值,返回一个long结果
LongToDoubleFunction double applyAsDouble(long value) 接收一个long值,返回一个double结果
LongToIntFunction int applyAsInt(long value) 接收一个long值,返回一个int结果
(5)
DoubleUnaryOperator double applyAsDouble(double operand) 接收一个double值,返回一个double
IntUnaryOperator int applyAsInt(int operand) 接收一个int值,返回一个int结果
LongUnaryOperator long applyAsLong(long operand) 接收一个long值,返回一个long结果 (6)
BiFunction<T,U,R> R apply(T t, U u) 接收一个T类型和一个U类型对象,返回一个R类型对象结果
(7)
BinaryOperator<T> T apply(T t, T u) 接收两个T类型对象,返回一个T类型对象结果
(8)
ToDoubleBiFunction<T,U> double applyAsDouble(T t, U u) 接收一个T类型和一个U类型对象,返回一个double
ToIntBiFunction<T,U> int applyAsInt(T t, U u) 接收一个T类型和一个U类型对象,返回一个int
ToLongBiFunction<T,U> long applyAsLong(T t, U u) 接收一个T类型和一个U类型对象,返回一个long (9) DoubleBinaryOperator double applyAsDouble(double left, double right) 接收两个double值,返回一个double结果
IntBinaryOperator int applyAsInt(int left, int right) 接收两个int值,返回一个int结果
LongBinaryOperator long applyAsLong(long left, long right) 接收两个long值,返回一个long结果 总结:
(1)以Unary开头的,表示一元的,泛型的类型只有一个,形参和返回值都是同一种类型
(2)xxFunction,说明形参的类型是xx类型的
(3)toXXFunction,说明返回值类型是xx类型
(4)xxToyyFunction,说明形参的类型是xx类型的,返回值类型是yy类型
(5)xxUnary开头的,表示一元,形参类型和返回值类型都是xx
(6)Bi开头,表示二元,形参类型是2个
(7)BinaryOperator,既是Bi开头表示两个形参,又是Operator结尾,表示形参和返回值类型是一样
(8)toXXBi开头的,表返回值类型是xx,并且形参是两个
(9)xxBinaryOperator,表示两个形参,又是Operator结尾,表示形参和返回值类型是一样

Lambda表达式(一)的更多相关文章

  1. 你知道C#中的Lambda表达式的演化过程吗?

    那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传递方法的类型.(用来传递数字的类型有int.float ...

  2. Linq表达式、Lambda表达式你更喜欢哪个?

    什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...

  3. 背后的故事之 - 快乐的Lambda表达式(一)

    快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...

  4. Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

    作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...

  5. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

  6. 背后的故事之 - 快乐的Lambda表达式(二)

    快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...

  7. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  8. Lambda 表达式递归用法实例

    注意: 使用Lambda表达式会增加额外开销,但却有时候又蛮方便的. Windows下查找子孙窗口实例: HWND FindDescendantWindows(HWND hWndParent, LPC ...

  9. Spark中Lambda表达式的变量作用域

    通常,我们希望能够在lambda表达式的闭合方法或类中访问其他的变量,例如: package java8test; public class T1 { public static void main( ...

  10. 释放Android的函数式能量(I):Kotlin语言的Lambda表达式

    原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...

随机推荐

  1. redis并发问题2

    转自https://mp.weixin.qq.com/s?__biz=MzI1NDQ3MjQxNA==&mid=2247485464&idx=1&sn=8d690fc6f878 ...

  2. Druid实现数据库连接用户密码加密

    使用ConfigFilter ConfigFilter的作用包括: 从配置文件中读取配置 从远程http文件中读取配置 为数据库密码提供加密功能 1 配置ConfigFilter 1.1 配置文件从本 ...

  3. bellman-ford算法求K短路O(n*m),以及判负环O(n*m)

    #include<iostream> #include<algorithm> #include<cstring> using namespace std; cons ...

  4. vulnhub-Os-hackNos-3

    vulnhub-Os-hackNos-3 nmap 192.168.114.0/24 查看存活主机,发现192.168.114.142. 具体探究: 发现80和22端口是开放的. dirb没扫出来啥, ...

  5. 干货满满!关于Pycharm远程开发

    可以在Windows中使用Pycharm编写代码,而代码的调试运行可以使用远程服务器中的python解释器. 在本地创建好工程项目(或从git上clone下代码)后,用Pycharm打开: 打开「To ...

  6. 记录jmeter使用beanshell断言获取复杂的json字符串参数值

    实战示例 测试场景 电商系统经常会涉及到商品的库存数量的压测,在用户下单前需要先做库存余量的判断,当余量不足时用户无法下单,保证商品的有效售卖 库存余量查询响应结果 响应结果一般是json字符串的形式 ...

  7. 057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和

    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和 本文知识点:求整型数组的数组元素的元素值累加和 案例:求整型数 ...

  8. 【题解】NOIP2018 旅行

    题目戳我 \(\text{Solution:}\) 首先题目描述有一点不准确:回头是必须要走完一条路无路可走的时候才能返回. 对于树的情况:显然贪心做就完事了. 对于基环树的情况:对于一个\(n\)条 ...

  9. 创建自定义视图在Android矩阵效果画布教程

    介绍 下面是一个快速教程,教你如何在Android中创建自定义视图.自定义视图创建一个矩阵雨效果. 本教程发布在http://www.androidlearner.com/. 背景 下面是关于如何工作 ...

  10. Centos 6.9安装 php5.6 过程中报错:Error: Package: php56w-mcrypt-5.6.40-1.w6.x86_64 (webtatic)

    在 CentOS 6.9 系统下安装 php 5.6 的过程中,执行如下命令: yum -y install php56w-pdo php56w-xml php56w-gd php56w-gd.x86 ...