面向对象的思想:做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
Java 8(JDK 1.8)中,加入了Lambda表达式的重量级新特性。
1 Runnable的实现举例
1.1 传统写法:
public class RunnableImpl implements Runnable {@Overridepublic 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(){@Overridepublic 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(){@Overridepublic 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>() {@Overridepublic 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;});//30invokeCal(40,20,(int a, int b)->{return a-b;});//20invokeCal(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对应的接口类型
- 有且只有一个抽象方法的接口称作函数式接口(后面会详细介绍函数式接口)