【jdk8新特性】Lambda表达式
为什么要用lambda表达式
先看这个例子
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("内部类多线程写法");
}
}).start();
new Thread(()->{
System.out.println("lambda多线程写法");
}).start();
}
结果
内部类多线程写法
lambda多线程写法
我们可以看出 用传统的内部类写法 代码冗余,而用lambda表达式 代码简单
lambda表达式格式与约束
格式:
(参数1,参数2....)->代码实现
约束:
首先lambda表达式只能用于参数为 接口且接口中只有一个抽象方法需要实现 与 变量为接口且接口中只有一个抽象方法需要实现。
我们 来看一下Thread需要的参数 Runnable接口的源码
public interface Runnable {
public abstract void run();
}
可以看出 Runnable接口 只有一个抽象方法,所以满足lambda的约束,所以可以用lambda表达式表示。
lambda表达式的几个例子
01:参数用lambda表达式书写
// 参数用lambda表达式书写
@Test
public void Test1(){
running(()->{
System.out.println("正在跑步");
});
}
public void running(Running running){
running.run();
}
Running接口
public interface Running {
void run();
}
可以看出Running接口 只有一个抽象方法,所以可以用lambda表达式
结果
正在跑步
02:变量为接口对象 对象的抽象方法实现用lambda
// 变量为接口对象 对象的抽象方法实现用lambda
@Test
public void Test2(){
person p = ()->{
System.out.println("吃");
};
p.eat();
}
person接口
interface person{
void eat();
}
结果
吃
03:对排序接口的实现 以及 forEach方法中lambda表达式的应用
// 对排序接口的实现 以及 forEach方法中lambda表达式的应用
@Test
public void Test3(){
ArrayList<Person> persons = new ArrayList<>();
persons.add(new Person("刘德华", 53, 174));
persons.add(new Person("张学友", 55, 176));
persons.add(new Person("刘德华", 56, 171));
persons.add(new Person("黎明", 54, 178));
Collections.sort(persons, (Person o1, Person o2) -> {
return o2.getAge() - o1.getAge(); // 降序
});
persons.forEach((t) -> {
System.out.println(t);
});
}
sort方法源码
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
Comparator接口部分代码
public interface Comparator<T> {
int compare(T o1, T o2);
}
可以看出sort方法中的参数二为 符合条件的接口 所以可以使用lambda表达式
forEach源码
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
final Object[] es = elementData;
final int size = this.size;
for (int i = 0; modCount == expectedModCount && i < size; i++)
action.accept(elementAt(es, i));
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Consumer接口源码
public interface Consumer<T> {
void accept(T t);
}
可以看出forEach的参数 也满足lambda的要求 所以可以使用lambda表达式,其中Consumer是我们后续需要学习的接口之一。