转自:https://www.cnblogs.com/hyyq/p/7425666.html
基础介绍
Lamda表达式,读作λ表达式,它实质属于函数式编程的概念,要理解函数式编程的产生目的,就要先理解匿名内部类。
场景:在使用时,再实现具体的业务逻辑;
先来看看传统的匿名内部类调用方式:
interface MyInterface{
void lMethod();
}
public class Main {
public static void test(MyInterface myInterface){
myInterface.lMethod();
}
public static void main(String[] args) {
test(new MyInterface() {
@Override
public void lMethod() {
System.out.println("Hello World!");
}
});
}
}
在主类中的这么几行代码,嵌套几层就为了输出一个Hello World!是不是很麻烦?但是由于java结构的完整性,我们还不得不那么做,现在JDK1.8来了。
再来看看使用Lamda表达式改写上面的代码:
interface MyInterface{
void lMethod();
}
public class Main {
public static void test(MyInterface myInterface){
myInterface.lMethod();
}
public static void main(String[] args) {
test(()->System.out.println("Hello World!"));
}
}
这就是Lamda表达式语言,为了解决匿名内部类繁杂的操作而出现。
Lamda语法有三种形式:
(参数) ->单行语句;
(参数) ->{多行语句};
(参数) ->表达式;
括号()可以大致理解为就是方法,里面是参数变量,在上面的例子中()->System.out.println("Hello World!") 前面的()代表void lMethod()方法,它没有入参,所以为空,->后面是一个单行语句;
如果->后面是多行语句,需要用{ }装起来,每条语句后需要有分号;
->后面也可以是一个表达式,如:a+b等。
(参数) ->单行语句:
interface MyInterface{
void lMethod(String str);
}
public class Main {
public static void test(MyInterface myInterface){
myInterface.lMethod("Hello World!");//设置参数内容
}
public static void main(String[] args) {
//首先在()中定义此表达式里面需要接收变量s,后面的单行语句中就可以使用该变量了
test((s)->System.out.println(s));
}
}
(参数) ->{多行语句}:
interface MyInterface{
void lMethod(String str);
}
public class Main {
public static void test(MyInterface myInterface){
myInterface.lMethod("Hello World!");//设置参数内容
}
public static void main(String[] args) {
//首先在()中定义此表达式里面需要接收变量s,后面的多行语句中就可以使用该变量了。注意:多行语句别少“;”号
test((s)->{
s=s+s;
System.out.println(s);
});
}
}
(参数) ->表达式:
interface MyInterface{
int lMethod(int a,int b);
}
public class Main {
public static void test(MyInterface myInterface){
int result=myInterface.lMethod(1,2);//设置参数内容,接收返回参数
System.out.println(result);
}
public static void main(String[] args) {
test((x,y)-> x*y );//调用方法
//相当于
// test((x,y)-> {return x*y;});
}
}
这样,Lamda表达式就看起来很简单了,有不有!
匿名内部类,我们比较常用的地方在哪儿?线程类Thread,以前我们可能这样写:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程操作!");
}
});
现在,使用Lamda表达式,简单写为:
new Thread(()->System.out.println("线程操作!"));
总结:利用Lamda表达式是为了避免匿名内部类定义过多无用的操作。
进阶
建立简单Bean类,方面后面的测试
import java.util.ArrayList;
import java.util.List;
public class Human {
private String name;
private int age;
public Human() {
}
public Human(String name, int age) {
this.name = name;
this.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;
}
@SuppressWarnings("serial")
public static List<Human> getAInitHumanList() {
return new ArrayList<Human>() {
{
add(new Human("guorao", 10));
add(new Human("mako", 12));
add(new Human("hel", 30));
add(new Human("lin", 28));
}
};
}
}
简单的排序方法
1、利用实现Comparator接口方式
public class HumanComparetor implements Comparator<Human> {
@Override
public int compare(Human h1, Human h2) {
if (h1.getAge() > h2.getAge()) {
return 1;
} else if (h1.getAge() == h2.getAge()) {
return 0;
} else {
return -1;
}
}
}
public static void main(String[] args) {
List<Human> humans = Human.getAInitHumanList();
Collections.sort(humans, new HumanComparetor());
System.out.println(humans);
}
2、利用内部类
public static void main(String[] args) {
List<Human> humans = Human.getAInitHumanList();
//方法内-局部类
class HumanComparetor implements Comparator<Human> {
@Override
public int compare(Human h1, Human h2) {
return h1.getAge() - h2.getAge();
}
}
Collections.sort(humans, new HumanComparetor());
System.out.println(humans);
}
利用新特性
1、利用lamdba方式
public static void main(String[] args) {
List<Human> humans = Human.getAInitHumanList();
//lamdba 表达式 ->
Collections.sort(humans, (Human h1, Human h2) -> h1.getAge() - h2.getAge());
System.out.println(humans);
}
2、利用Comparator和lamdba表达式多条件排序
public static void main(String[] args) {
List<Human> humans = Human.getAInitHumanList();
////lamdba 表达式 ::
Collections.sort(humans, Comparator.comparing(Human::getAge).thenComparing(Human::getName));
System.out.println(humans);
}
3、用Comparator接口方式多条件排序
public static void main(String[] args) {
List<Human> humans = Human.getAInitHumanList();
//直接用list.sort
humans.sort(Comparator.comparing(Human::getAge).thenComparing(Human::getName));
System.out.println(humans);
}
解释:Comparable和Comparator
- 1、Comparable为内部比较类,是实现的对象自身与其他对象进行比较
object.compareTo(object2)
- 2、Comparator为外部比较类,是实现某种对象之间的属性、值之间的比较方式;
其实Comparator就是一种典型的策略模式;
ComparatorImpl comparator = new ComparatorImpl();
comparator.compare(object1, object2)