函数式编程思想
函数就是有输入量,输出量的一套计算方案。函数式编程思想就是强调做什么,而不是以什么形式去做,避免创建对象或者面向对象这种形式来做。
面向对象的思想:想要做一件事情,就要找能做这件事情的对象,然后通过对象去调用方法
函数式编程思想:只要能获取到结果就可以,谁去做,怎么做不重要,重视结果,不重视过程
开启新线程时,当重写Runnable接口的run方法时会有很多冗余的东西
即使使用最简洁的匿名内部类仍然不能避免要重写方法的返回值,方法参数等这些不必要的东西,但是以Runnable为例,实际上重点是在其中重写的run方法体上
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" new a thread");
}
}).start();
}
Lambda表达式
是java8的新特性,是Oracle公司在2014年发布1.8之后将怎么做转换成做什么,从而打开了新世界的大门
开启新线程时,重写Runnable的run方法用Lambda方式来实现如下:代码大大简化
//使用lambda表达式来开启一个新线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"使用Lambda表达式写法开启线程");
}).start();//Thread-1使用Lambda表达式写法开启线程
Lambda表达式的语法:
Lambda由三部分组成:
Lambda的标准格式为:
(参数类型 参数名称) -> { 代码语句 }
格式的说明:
():中其实就是接口中抽象方法的参数,没有参数就空着,有参数就写出参数,多个参数用逗号分离
->:传递的意思,就是把参数传递给方法使用
{}: 重写方法的方法体
//定义一个类 Person
package com.kou.lambda.demo2;
public class Person {
private String name;
private int 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;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//测试类中使用匿名内部类和lambda表达式看效果
public static void main(String[] args) {
Person[] persons = {new Person("Karen",19),new Person("Kyle",33),new Person("Kate",17),new Person("Kevin",21)};
//匿名内部类实现comparator接口
Arrays.sort(persons, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for (Person p1 :persons
) {
System.out.println(p1);
}
//通过lambda有参数的形式实现comparator接口 降序看看结果
Arrays.sort(persons, (Person o1, Person o2) -> {return o2.getAge() - o1.getAge();});
for (Person p1 :persons
) {
System.out.println(p1);
}
}
有参数有返回值的lambda表达式来实现自定义接口方法
//定义计算接口
public interface Caculator {
int caculate(int a, int b);
}
//测试类用匿名内部类或者是lambda表达式类实现接口
public static void main(String[] args) {
//匿名内部类来调用计算接口
invokeCalc(3, 4, new Caculator() {
@Override
public int caculate(int a, int b) {
return a + b;
}
});
//lambda实现计算接口
invokeCalc(5,6,(int a, int b) -> {return a + b;});
}
public static void invokeCalc(int a, int b, Caculator cacul){
int result = cacul.caculate(a,b);
System.out.println(result);
}
Lambda的省略格式
省略的原则:只要可推导,即可省略
具体省略的规则:
(参数列表)中的参数的类型可以省略,
(参数列表)中的参数如果只有一个,那么类型和()都可以省略。
{一些代码}中, 如果只有一行代码,无论有无返回值**{}和return以及;**都可省略。要省略都必须省略,不省略就都别省
//以前的Lambda省略:
public static void main(String[] args) {
//使用lambda表达式来开启一个新线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"使用Lambda表达式写法开启线程");
}).start();//Thread-1使用Lambda表达式写法开启线程
//优化简写Lambda表达式1
new Thread(() -> System.out.println(Thread.currentThread().getName()+"使用Lambda简写形式表达式写法开启线程")).start();
//通过lambda有参数的形式实现comparator接口 降序看看结果
Arrays.sort(persons, (Person o1, Person o2) -> {return o2.getAge() - o1.getAge();});
for (Person p1 :persons
) {
System.out.println(p1);
}
//通过Lambda有参数的简化形式
Arrays.sort(persons,(o1,o2)->o1.getAge()-o2.getAge());
//lambda实现计算接口
invokeCalc(5,6,(int a, int b) -> {return a + b;});
//Lambda的简化形式
invokeCalc(5,8,(a,b) -> a+b);
}
使用Lambda表达式的前提:
使用Lambda必须要有接口,且接口中必须有且只有一个抽象方法
不论是JDK内置的Runnable,Comparator接口还是自己定义的接口,要想使用Lambda表达式就必须满足以上条件。
使用Lambda表达式必须具有上下文推断,
也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda表达式作为该接口的实例。
注意:有且仅有一个方法的接口也叫函数式接口。