面向对象的思想:
做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情。
函数式编程思想:
只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
使用传统代码
/*
使用实现Runnable接口的方式实现多线程程序
*/
public class Demo01Runnable {
public static void main(String[] args) {
//创建Runnable接口的实现类对象
Runnable run = new RunnableImpl();
//创建Thread类对象,构造方法中传递Runnable接口的实现类
Thread t = new Thread(run);
//调用start方法开启新线程,执行run方法
t.start();
//简化代码,使用匿名内部类,实现多线程程序
//用一个接口进行接收
Runnable r = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "新的线程创建了");
}
};
new Thread(r).start();
//继续简化代码
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "新的线程创建了");
}
}).start();
}
}
使用lambda表达式
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标准格式
先定义一个接口
/*
定义一个厨子Cook接口,内涵唯一的抽象方法makeFood
*/
public interface Cook {
//定义无参数无返回值的方法makeFood
public abstract void makeFood();
}
/*
需求:
给定一个厨子Cook接口,内涵唯一的抽象方法,makeFood,且无参数,无返回值
使用Lambda的标准格式调用invokeCook方法,打印输出"吃饭啦!"字样
*/
public class Demo01Cook {
public static void main(String[] args) {
//调用invokeCook方法,参数是Cook接口没传递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();
}
}
参数和返回值的练习
/*
Lambda表达式有参数有返回值的练习
需求:
使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
*/
public class Demo01Arrays {
public static void main(String[] args) {
//使用数组存储多个Person对象
Person[] arr = {
new Person("柳岩", 18),
new Person("高圆圆", 19),
new Person("杨幂", 17),
};
//对数组中的Person对象使用Arrays的sort方法通过年龄进行升序(前面减后面)排序
// Arrays.sort(arr, new Comparator<Person>() {
// @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);
}
}
}
自定义接口的练习
首先自定义一个接口
/*
给定一个计算器Calculator接口,内含抽象方法calc,可以将两个int数字相加得到和值
*/
public interface Calculator {
//定义一个计算两个int整数和的方法并返回结果
public abstract int calc(int a,int b);
}
/*
Lambda表达式有参数有返回值的练习
需求:
给定一个计算器Calculator接口,内含抽象方法calc可以将两个int数字相加得到和值
使用Lambda的标准格式调用invokeCalc方法,完成120和130的相加计算
*/
public class Demo01Calculator {
public static void main(String[] args) {
//调用invokeCalc方法,方法的参数是一个接口,可以使用匿名内部类
invokeCalc(10, 20, new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
});
//使用Lambda表达式简化匿名内部类的书写
invokeCalc(130, 120, (int a, int b) -> {
return a + b;
});
}
/*定义一个方法
参数传递两个int类型的整数
参数传递Calculator接口
方法内部调用Calculator中的方法calc结算两个整数的和
*/
public static void invokeCalc(int a, int b, Calculator c) {
int sum = c.calc(a, b);
System.out.println(sum);
}
}
Lambda省略格式和使用前提
1.使用Lambda必须具有接口,且要求接口中有仅有一个抽象方法。
2.使用Lambda必须具有上下文推断,也就是方法的参数或局部变量类型必须为Lambda对相应的接口类型,才能使用Lambda作为该接口的实例。
备注:有且仅有一个抽象方法的接口,成为"函数式接口"