函数式编程语言操纵代码片段就像操作数据一样容易。 虽然 Java 不是函数式语言,但 Java 8 Lambda 表达式和方法引用 (Method References) 允许你以函数式编程。
Lambda 函数式编程、
Java虽然是属于面向对象的语言,但是在JDK1.8之后加用了Lambda函数式,使复杂的程序结构变得简洁易懂 ~
两种的不同
面向对象:(Object Oriented)
解决某个问题时,首先找出解决问题的对象,然后通过调用对象的方法去解决。(注重的是结局的过程)
函数式:(Functional Programming)
只获取结果(不重视过程)
体验Lambda的更优写法:
借助Java 8 的全新语法,上述Runnabel 接口的匿名内部类写法可以通过更简单的Lambda表达式等效完成!
普通的匿名内部类方法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+ "我是个好人 ");
}
}).start();
```
** 函数式Lambda的方法(无参)**
```java
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"我爱学习JAVA ");
}){
}.start();
结果如下:
匿名内部类的优缺点
**优点:**省去了实现类的定义。
**不足:**内部类的结构复杂,可读性不是很好。
Lambda 结构 由三部分组成:
- 一个参数 () 接口中抽象方法的方法参数,没有就空着,有多个就用逗号隔开
- 一个箭头 -> 将参数传递给方法体
- 一段逻辑代码 重写接口抽象方法的方法体
(参数列表) -> { 重写的逻辑代码}
实例 一:
使用数组储存多个Person 对象
对数组中的对象用 Arrays . sort方法 对对象的年龄进行排序
一:先定义一个Person类 其实 不用这么 麻烦 get set toString 就OK
package Thread2_Lambda;
public class Person_01 {
private String name ;
private int age ;
public Person_01(){
}
public Person_01(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person_01{" +
"name='" + name + '\'' +
", 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;
}
}
然后在创建一个数组 用来储存对象的信息–>Arrays.sort排列数组–>遍历得出结论
public class Demo01_Person01 {
public static void main(String[] args) {
Person_01 arr [] = {
new Person_01("小美",20),
new Person_01("红红",16),
new Person_01("迪丽热巴",19),
new Person_01("鞠经纬",22)
};
一:匿名内部类的方法实现:
//利用Arrays.sort 方法(前边 - 后边)对其排序
// 原始方法
Arrays.sort(arr, new Comparator<Person_01>() {
@Override
public int compare(Person_01 o1, Person_01 o2) {
return o1.getAge()-o2.getAge();
// 升序排序 年龄
}
});
// 遍历数组
for(Person_01 p : arr) {
System.out.println(p);
}
二:Lambda的简便方法:
这里面的()内要传递参数 ,对于多个参数的
// 利用Lambda 进行数组排序 ,简化匿名内部类 ()-> 里面有参数 分别为 Person_01 o1 ,Person_01 o2
Arrays.sort(arr,(Person_01 o1 ,Person_01 o2 )->{
return o1.getAge()-o2.getAge();
});
再遍历一下 :和上面一样 这里不再赘述。
运行结果:(#^. ^#) 这里的年龄哈哈哈哈可能有点飘~~
实例 二:
先 interface 三个接口 —> 然后通过接口名去调用方法即可
/**
* Functional Programming
* BY Howe
*/
// 先创建三个接口
interface Description{
String brief();
}
interface Body {
String detailed(String head );
}
interface Multi{
String twoArg(String head, Double d);
}
public class LambdaDemo2_FromJava_8 {
static Body body = h -> h + "Is a good MAN ! ";
static Body body2 = h -> h + " Love Java ! ";
static Multi mu = (h,d)-> h + d;
static Description desc = () -> "short info";
static Description morelines = () -> {
System.out.println("我是个好人@*@");
return "我是个 Java 小菜鸟 ";
};
public static void main(String[] args) {
System.out.println(body.detailed("Howe "));
System.out.println(body2.detailed(" 张 "));
System.out.println(desc.brief()); // 为空
System.out.println(mu.twoArg("Howe",666.666));
System.out.println(morelines.brief());
}
}
结果:
这里有个要关注点:对于body 和 body1 只有一个参数时,可以省略 () ,但 这是一个特例。(我们不能搞特殊化)
通常情况下不管是否有参数都是要带 (),为了追求一致性。
对于多个参数,将参数列表放在括号 ( ) 中
到目前为止,所有 Lambda 表达式方法体都是单行。 该表达式的结果自动成为 Lambda 表达式的返回值,在此处使用 return 关键字是非法的。 这是 Lambda 表达式简化相应语法的另一种方式。
如果在 Lambda 表达式中确实 需要多行 ,则必须将这些行放在花括号 { } 中。 在这种情况下,就需要使用 return。
总结:三个重点 ( ) 、-> 、 { }