java8——Lambda表达式
1.简介:
jdk1.8中引入Lambda表达式,其作用是使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。
eg:摘自百度百科:
没有使用Lambda的老方法:
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent actionEvent){
System.out.println("Action detected");
}
});
使用lambda后:
button.addActionListener( actionEvent -> {
System.out.println("Action detected");
});
Lambda表达式中,在Thread多线程的使用过程中较为频繁:如:
使用匿名内部类的时候重写run方法:
Runnable runnable1=new Runnable(){
@Override
public void run(){
System.out.println("Running without Lambda");
}
};
使用Lambda后:
Runnable runnable2=()->System.out.println("Running from Lambda");
lambda表达式的标准格式:
有三部分
一些参数
一个箭头
一段代码
格式:
(参数列表)->{一些重写方法的代码}
解释说明格式:
()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
->传递的意思,把参数传递给方法体{}
{}重写接口的抽象方法的方法体
2,函数式编程思想概述
2.1 区别:
面向对象的思想:
·做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:
·只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
3. 讲述
例如:在多线程中:创建一个实现类,用于实现RUnnable接口,重写了run方法
public class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
}
创建主类,用于实现
public class Demo1Runnable {
public static void main(String[] args) {
RunnableImpl runnable=new RunnableImpl();
Thread t=new Thread(runnable);
t.start();
//简化代码,匿名内部类
Runnable runnable1= new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
};
new Thread(runnable1).start();//调用线程的启动。
}
这是存在冗余的程序代码块,
简化一:
public class Demo1Runnable {
public static void main(String[] args) {
RunnableImpl runnable=new RunnableImpl();
Thread t=new Thread(runnable);
t.start();
//简化代码,匿名内部类
Runnable runnable1= new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
};
new Thread(runnable1).start();
//继续简化
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
}).start();
}
}
采用匿名内部类,实现线程。
总结:
简化该线程的方法:
1.
Runnable runnable1= new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
};
new Thread(runnable1).start();
2. 这段代码是1中的综合
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
}).start();
3. 使用lambda进行简化codes
lambda表达式的标准格式:
* 有三部分
* 一些参数
* 一个箭头
* 一段代码
* 格式:
* (参数列表)->{一些重写方法的代码}
* 解释说明格式:
* ()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
* ->传递的意思,把参数传递给方法体{}
* {}重写接口的抽象方法的方法体
codes:
public class Demo02Lambda {
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();
//优化省略lambda
new Thread(()->System.out.println(Thread.currentThread().getName()+"新的线程创建了---")
) .start();
}
}
案例二(无参无返回值):
给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:
public interface Cook {
public abstract void makeFood();
}
在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:
解答:
public class Demo1Cook {
public static void main(String[] args) {
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃放了");
}
});
// 使用lambda表达式
invokeCook(()->{
System.out.println("吃饭了");
});
//省略lambda
invokeCook(()->System.out.println("吃饭了"));
}
//定义方法,参数传递cook接口,方法内部调用cook接口中的方法makeFood
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
案例三(参数和返回值):
需求:
使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
1.创建Person类
package com.lambdaDemo;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
传统的排序:
import java.util.Arrays;
import java.util.Comparator;
public class Demo06Comparator {
public static void main(String[] args) {
// 本来年龄乱序的对象数组
Person[] array = {
new Person("古力娜扎", 19),
new Person("迪丽热巴", 18),
new Person("马尔扎哈", 20) };
// 匿名内部类
Comparator<Person> comp = new Comparator<Person>({
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() ‐ o2.getAge();
}
};
Arrays.sort(array, comp); // 第二个参数为排序规则,即 Comparator接口实例
for (Person person : array) {
System.out.println(person);
}
}
}
知识点:创建对象数组:
对象名[] 数组名称={new 对象名(),new 对象名(),new 对象名(), }
排序:
使用Comparator
Comparator<Person> comp = new Comparator<Person>({
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() ‐ o2.getAge();
}
};
升序是参数1-参数2,降序是参数2-参数1.
记得使用Arrays.sort(array, comp);进行排序,然后遍历数组即可
使用Lambda的排序:
public class Demo1Arrays {
public static void main(String[] args) {
Person[] arr={
new Person("cym",11),
new Person("yyh",221),
new Person("jhj",13),
};
Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
for (Person p : arr) {
System.out.println(p);
}
//使用lambda表达式简化匿名内部类
System.out.println("------------使用lambda表达式");
Arrays.sort(arr,(Person o1,Person o2)->{
return o2.getAge()-o1.getAge();
});
Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
for (Person p : arr) {
System.out.println(p);
}
}
}
案例三:有参有返回
public interface Calculate {
//定义两个int和方法
public abstract int calc(int a,int b);
}
使用lambda
package com.lambdaDemo1;
public class Demo1Calculator {
public static void main(String[] args) {
//调用invakeCalc方法,参数是接口,可以使用匿名内部类
invokeCalc(10, 20, new Calculate() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
//使用lambda表达式简化匿名内部类的书写
invokeCalc(10,20,(int a,int b)->{
return a+b;
});
//省略
invokeCalc(10,20,(a,b)-> a+b);
}
//定义一个方法,参数传递两个int类型的整数,参数cdCalculator接口,
// 方法内部电泳Calculator中的方法calc计算和
public static void invokeCalc(int a,int b ,Calculate calculate){
int sum= calculate.calc(a,b);
System.out.println(sum);
}
}
Lambda的省略《规则》:
/*可推到可省略
* 凡是根据上下文推到出来的内容,都可以省略书写
* 可以省略的内容:
* 1,(参数列表):括号中参数列表的数据类型,可以省略不写
* 2,(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
* 3.{代码}ruguo {}的代码只有一行,无论是否有返回值,都可以省略{}return 和分号
* ·要省略都一起省略
1. 省略前:
new Thread(()-> {
System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
}
) .start();
省略后:
new Thread(()->System.out.println(Thread.currentThread().getName()+"新的线程创建了---")
) .start();
explanation:如果{代码块}中只有一行代码,则可以省去{},和;
2. 省略前:
invokeCook(()->{
System.out.println("吃饭了");
});
省略后:
invokeCook(()->System.out.println("吃饭了"));
explanation:省略了{}和; 因为代码块就一句;
3. 省略前:
Arrays.sort(arr,(Person o1,Person o2)->{
return o2.getAge()-o1.getAge();});
省略后:
Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
explanation:变量名一样可以省略,代码块就一句话,可以省略return和{} ;
4. 省略前:
invokeCalc(10,20,(int a,int b)->{
return a+b;
});
省略后:
invokeCalc(10,20,(a,b)-> a+b);
explanation:同上
github-----》》》"lambda"
博客网站 https://yamon.top
个人网站 https://yamon.top/resume
GitHub网站 https://github.com/yamonc
欢迎前来访问