面向对象的思想:做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
Java 8(JDK 1.8)中,加入了Lambda表达式的重量级新特性。
1 Runnable的实现举例
1.1 传统写法:
public class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新线程创建了");
}
}
public class Test {
public static void main(String[] args) {
RunnableImpl ri = new RunnableImpl();
Thread t = new Thread(ri);
t.start();
}
}
1.2 简化写法-匿名内部类
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"新线程创建了");
}
}).start();
}
1.3 Lambda去除冗余
public static void main(String[] args) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"新线程创建了");
}).start();
}
2 Lambda表达式格式
- 一些参数
- 一个箭头
- 一段代码
- 格式:(参数列表)-> (重写方法的代码)
3 无参数无返回的Lambda
定义接口类
public interface Cook {
public abstract void makeFood();
}
定义测试类
public class Test {
public static void main(String[] args) {
//匿名内部类
invokeCook(new Cook(){
@Override
public void makeFood() {
System.out.println("吃饭了");
}
});
//Lambda表达式
invokeCook(()->{
System.out.println("吃饭了");
});
}
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
4 有参数和返回值的Lambda
4.1 传统写法
public class Test {
public static void main(String[] args) {
Person[] arr = {
new Person("张三",10),
new Person("李四",20),
new Person("王五",30)
};
//按照年龄升序 前-后
Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for (Person person : arr) {
System.out.println(person);
}
}
}
4.2 Lambda写法
public class Test {
public static void main(String[] args) {
Person[] arr = {
new Person("张三",10),
new Person("李四",20),
new Person("王五",30)
};
//按照年龄升序 前-后
Arrays.sort(arr, (Person o1, Person o2)-> {
return o1.getAge() - o2.getAge();
});
for (Person person : arr) {
System.out.println(person);
}
}
}
4.3 自定义接口练习
public interface Calculator {
public abstract int cal(int num1, int num2);
}
public class Test {
public static void main(String[] args) {
invokeCal(10,20,(int a, int b)->{
return a+b;});//30
invokeCal(40,20,(int a, int b)->{
return a-b;});//20
invokeCal(40,20,(int a, int b)->{
return a*b;});//800
}
public static void invokeCal(int a, int b, Calculator c){
int sum = c.cal(a,b);
System.out.println(sum);
}
}
5 Lambda的省略格式和使用前提
- 可以省略参数列表括号中的参数类型
- 如果参数只有一个类型和()都可以省略
- 如果{}中的代码只有一行都可以省略{}、return、分号 (三者要一起省略)
public class Test {
public static void main(String[] args) {
//Lambda表达式
invokeCook(()->System.out.println("吃饭了"));
}
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
public class Test {
public static void main(String[] args) {
Person[] arr = {
new Person("张三",10),
new Person("李四",20),
new Person("王五",30)
};
//按照年龄升序 前-后
Arrays.sort(arr, (o1, o2)-> return o1.getAge() - o2.getAge());
}
}
使用前提:
- 必须具有接口,且接口中只有一个抽象方法。【Runnable、Comparator和自定义类型都只有一个抽象方法】
- 方法的参数或局部变量类型必须式Lambda对应的接口类型
- 有且只有一个抽象方法的接口称作函数式接口(后面会详细介绍函数式接口)