文章目录
Java8-Lambda表达式
开篇示例
package com.nike.demo01;
import java.util.function.Function;
public class SimpleLambda {
public static void main(String[] args) {
//执行一个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello,World!");
}
}).run();
new Thread(() -> System.out.println("Hello,World!")).run();
//把代码逻辑当作参数进行传递
Integer age = getAge(a -> Integer.parseInt(a), "22");
System.out.println(age);
}
public static Integer getAge(Function<String,Integer> function,String args){
return function.apply(args);
}
}
Lambda表达式简介
什么是Lambda?
Lambda是Java8添加的一个新特性,说白了,Lambda就是一个匿名函数。
为什么要使用Lambda表达式?
使用Lambda表达式可以对一个接口进行非常简洁的实现。
Lambda对接口的要求!
虽然我们可以使用Lambda对某些接口进行简单的实现,但并不是所有的接口都可以使用Lambda表达式来实现,要求接口中定义的必须实现的抽象方法只能是一个。
在Java8对接口加了一个新特性:default,被default修饰的方法可以有一个默认实现。
@FunctionalInterface修饰函数式接口,被修饰的接口中的抽象方法只有一个。
package com.nike.demo01;
public class Program {
public static void main(String[] args) {
//1.使用接口实现类
Comparator comparator = new MyComparator();
//2.使用匿名实现类
Comparator comparator1 = new Comparator() {
@Override
public int compare(int a, int b) {
return a - b;
}
};
//3.使用Lambda表达式
Comparator comparator2 = (a, b) -> a - b;
}
}
class MyComparator implements Comparator {
@Override
public int compare(int a, int b) {
return a - b;
}
}
@FunctionalInterface
interface Comparator {
int compare(int a, int b);
}
Lambda基础语法
准备工作:准备若干个接口
1.无参数无返回值的函数式接口
@FunctionalInterface
public interface NoneReturnNoneParameterInterface {
void test();
}
2.单一参数无返回值的函数式接口
@FunctionalInterface
public interface NoneReturnSingleParameterInterface {
void test(int n);
}
3.多参数无返回值的函数式接口
@FunctionalInterface
public interface NoneReturnMultiParameterInterface {
void test(int a,int b);
}
4.无参数有返回值的函数式接口
@FunctionalInterface
public interface SingleReturnNoneParameterInterface {
int test();
}
5.单一参数有返回值的函数式接口
@FunctionalInterface
public interface SingleReturnSingleParameterInterface {
int test(int a);
}
6.多参数有返回值的函数式接口
@FunctionalInterface
public interface SingleReturnMultiParameterInterface {
int test(int a,int b);
}
Lambda实现函数式接口
import com.nike.demo01.interfaces.*;
public class Syntax01 {
public static void main(String[] args) {
//Lambda基础语法
//Lambda是一个匿名函数
//参数列表,方法体
//():用来描述参数列表
//{}:用来描述方法体
//->:Lambda运算符,读作goes to
//1.无参无返回
NoneReturnNoneParameterInterface lambda1=()->{
System.out.println("无参无返回值");
};
lambda1.test();
//2.单一参数无返回值
NoneReturnSingleParameterInterface lambda2=(a)->{
System.out.println("单一参数无返回值:"+a);
};
lambda2.test(20);
//3.多个参数无返回值
NoneReturnMultiParameterInterface lambda3 = (a,b) ->{
System.out.println("多个参数无返回值:"+a+","+b);
};
lambda3.test(20,21);
//4.有返回值无参数
SingleReturnNoneParameterInterface lambda4 = ()->{
return 20;
};
int test = lambda4.test();
System.out.println("有返回值无参数:"+test);
//5.有返回值单一参数
SingleReturnSingleParameterInterface lambda5 = (a) -> {
System.out.println("单一参数:"+a);
return a;
};
int test1 = lambda5.test(30);
System.out.println("有返回值单一参数:"+test1);
//6.有返回值多个参数
SingleReturnMultiParameterInterface lambda6 = (a,b) -> {
System.out.println("多个参数:"+a+","+b);
return a+b;
};
int test2 = lambda6.test(20, 25);
System.out.println("有返回值多个参数:"+test2);
// 无参无返回值
// 单一参数无返回值:20
// 多个参数无返回值:20,21
// 有返回值无参数:20
// 单一参数:30
// 有返回值单一参数:30
// 多个参数:20,25
// 有返回值多个参数:45
}
}
Lambda语法精简
package com.nike.demo01.syntax;
import com.nike.demo01.interfaces.*;
public class Syntax01 {
public static void main(String[] args) {
//Lambda语法精简
//1.参数类型:
//由于在接口的抽象方法中已经定义了参数的数量和类型,所以在Lambda表达式中
//参数类型可以省略
//备注:如果省略参数类型,则每一个参数的类型都要省略。
//2.参数小括号:
//如果参数列表中,参数数量只有一个,此时小括号可以省略;
//3.方法大括号:如果方法体中只有一条语句,大括号可以省略;
//4.如果方法体中唯一一条语句时返回语句,则在省略掉大括号同时省略掉return关键字;
NoneReturnNoneParameterInterface lambda1 = () -> System.out.println("无参无返回值");
lambda1.test();
//2.单一参数无返回值
NoneReturnSingleParameterInterface lambda2 = a -> System.out.println("单一参数无返回值:" + a);
lambda2.test(20);
//3.多个参数无返回值
NoneReturnMultiParameterInterface lambda3 = (a, b) -> System.out.println("多个参数无返回值:" + a + "," + b);
lambda3.test(20, 21);
//4.有返回值无参数
SingleReturnNoneParameterInterface lambda4 = () -> 20;
int test = lambda4.test();
System.out.println("有返回值无参数:" + test);
//5.有返回值单一参数
SingleReturnSingleParameterInterface lambda5 = a -> a+10 ;
int test1 = lambda5.test(30);
System.out.println("有返回值单一参数:" + test1);
//6.有返回值多个参数
SingleReturnMultiParameterInterface lambda6 = (a, b) -> a + b;
int test2 = lambda6.test(20, 25);
System.out.println("有返回值多个参数:" + test2);
// 无参无返回值
// 单一参数无返回值:20
// 多个参数无返回值:20,21
// 有返回值无参数:20
// 有返回值单一参数:40
// 有返回值多个参数:45
}
}
Lambda语法进阶
import com.nike.demo01.interfaces.SingleReturnSingleParameterInterface;
public class Syntax02 {
public static void main(String[] args) {
//方法引用
//可以快速的将一个Lambda表达式的实现指向一个已经实现的方法。
//语法:方法的隶属者::方法名
//注意:
//1.参数数量和类型一定要和接口中定义的方法一致;
//2.返回值类型一定要和接口中定义的方法一直。
SingleReturnSingleParameterInterface lambda1 = a -> a+10;
int test = lambda1.test(30);
System.out.println(test);
SingleReturnSingleParameterInterface lambda2 = a -> add(a);
int test1 = lambda2.test(40);
System.out.println(test1);
//方法引用:引用了Syntax02的add方法的实现
SingleReturnSingleParameterInterface lambda3 = Syntax02::add;
int test2 = lambda3.test(50);
System.out.println(test2);
}
private static int add(int a){
return a + 10;
}
}
Lambda表达式构造方法的引用
public class Person {
public String name;
public int age;
public Person() {
System.out.println("Person无参构造执行了");
}
public Person(String name, int age) {
System.out.println("Person有参构造执行了");
this.name = name;
this.age = age;
}
}
import com.nike.demo01.data.Person;
public class Syntax03 {
public static void main(String[] args) {
PersonFactory factory = () -> new Person();
//构造方法的引用:
PersonFactory factory1 = Person::new;
Person person = factory1.newPerson();
//有参构造的引用
PersonCreator creator = Person::new;
Person person1 = creator.getPerson("nike", 22);
}
}
interface PersonFactory {
Person newPerson();
}
interface PersonCreator {
Person getPerson(String name, int age);
}
Lambda表达式的使用
import com.nike.demo01.data.Person;
import java.util.ArrayList;
import java.util.List;
public class Exercise01 {
//集合排序
public static void main(String[] args) {
//需求:已知在一个List集合中有若干个Person对象。将这些person按照
//年龄进行降序排序
List<Person> personList = new ArrayList<>();
personList.add(new Person("小明",20));
personList.add(new Person("小杠",16));
personList.add(new Person("小花",18));
personList.add(new Person("小白",26));
personList.add(new Person("小治",22));
personList.add(new Person("小美",15));
personList.add(new Person("小峰",28));
personList.add(new Person("小泽",23));
//Lambda表达式实现Comparable接口实现排序
personList.sort( (p1,p2)-> p2.age-p1.age );
for (Person person : personList) {
System.out.println(person);
}
}
}
import com.nike.demo01.data.Person;
import java.util.TreeSet;
public class Exercise02 {
public static void main(String[] args) {
//TreeSet
//使用Lambda表达式实现Comparator接口,并实例化一个TreeSet对象
TreeSet<Person> peoples = new TreeSet<>((o1, o2) -> {
if (o1.age > o2.age){
return -1;
}else{
return 1;
}
});
peoples.add(new Person("小明", 20));
peoples.add(new Person("小杠", 16));
peoples.add(new Person("小花", 18));
peoples.add(new Person("小白", 26));
peoples.add(new Person("小治", 22));
peoples.add(new Person("小美", 16));
peoples.add(new Person("小峰", 28));
peoples.add(new Person("小泽", 23));
for (Person people : peoples) {
System.out.println(people);
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Lambda表达式实现集合的遍历
*/
public class Exercise03 {
public static void main(String[] args) {
List<Integer> integers = new ArrayList<>();
Collections.addAll(integers,1,2,3,4,5,6,7,8,9);
//将集合中的每一个元数带入方法accept中
//integers.forEach(System.out::println);
integers.forEach(ele -> {
if (ele%2==0){
System.out.println(ele);
}
});
}
}
import com.nike.demo01.data.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/**
* 使用Lambda表达式删除集合中满足条件的元素
*/
public class Exercise04 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("小明",20));
personList.add(new Person("小杠",16));
personList.add(new Person("小花",18));
personList.add(new Person("小白",26));
personList.add(new Person("小治",22));
personList.add(new Person("小美",15));
personList.add(new Person("小峰",28));
personList.add(new Person("小泽",23));
//删除集合中年龄大于20岁的元素。
// ListIterator<Person> listIterator = personList.listIterator();
// while(listIterator.hasNext()){
// Person person = listIterator.next();
// if (person.age>20){
// listIterator.remove();
// }
// }
// System.out.println(personList);
//Lambda表达式实现
//将集合中的每一元素都带入到test方法中,如果返回值为ture则删除该元素
personList.removeIf(p -> p.age>20);
personList.forEach(System.out::println);
}
}
/**
* 使用lambda表达式简洁的实现线程的实例化
*/
public class Exercise05 {
public static void main(String[] args) {
//需求开启一条线程
new Thread(()-> System.out.println("开启了一条新线程")).run();
}
}
系统内置的函数式接口
//系统内置的一些函数式接口
//Predicate<T> :参数T 返回值boolean
// IntPredicate :int -> boolean
// LongPredicate :long -> boolean
//Consumer<T> :参数T 返回值void
// IntConsumer :int -> void
// LongConsumer :long -> void
// DoubleConsumer :double -> void
//Function<T,R> :参数T 返回值R
// IntFunction<R> :int -> R
// LongFunction<R> :long -> R
// DoubleFunction<R> :double -> R
// IntToLongFunction<R> :int -> long
// IntToDoubleFunction<R> :int -> double
// LongToIntFunction<R> :long -> int
// LongToDoubleFunction<R> :long -> double
//Supplier<T> :无参 返回值T
//UnaryOperator<T> :参数T 返回值T
//BinaryOperator<T>:参数T,T 返回值T
//BiFunction<T,U,R>:参数T,U 返回值R
//BiPredicate<T,U> :参数T,U 返回值boolean
//BiConsumer<T,U> :参数T,U 返回值void
Lambda表达式闭包问题
import java.util.function.Supplier;
public class Closure {
public static void main(String[] args) {
int num = getNum().get();
System.out.println(num);
}
private static Supplier<Integer> getNum(){
int num = 10;
//闭包会提升包围变量的生命周期
return () -> {
return num;
};
}
}
import java.util.function.*;
public class Closure {
public static void main(String[] args) {
int a= 20;
//闭包:在Lambda中引用某一个局部变量必须保证它是一个常量
Consumer<Integer> c = ele -> System.out.println(a);
c.accept(a);
}
}