Lambda学习总结
参考资料:https://www.bilibili.com/video/av50530058/?p=1
1. Lambda表达式是什么 ?
:lambda 是一个匿名函数(对一个接口的匿名实现);
2.Lambda的组成?
:参数列表 + 方法体
// () : 参数列表 // {} : 方法体 // -> : 运算符 (Goes to)
3. Lambda基础语法?
(这里有实现定义好的几个接口,方法名都为test,根据代码上的注释可以大概可以理解是什么意思,接口在这里不写了)
//无返回 无参 LambdaNoReturnNoParam lambda1 = () -> { //实现方法的 方法体 System.out.println("无返回值 无参数!"); }; lambda1.test(); //无返回 单个参数 LambdaNoReturnOneParam lambda2 = (int a) -> { System.out.println(a + 1); }; lambda2.test(2); //无返回 多个参数 LambdaNoReturnMutipleParam lambda3 = (int a, int b) -> { System.out.println(a + b); }; lambda3.test(10,20); //有返回值 无参数 LambdaReturnNoParam lambda4 = () -> { return 12345; }; int ret = lambda4.test(); System.out.println(ret); //有返回值 单个参数 LambdaReturnOneParam lambda5 = (int a) -> { return a + 1; }; System.out.println(lambda5.test(44)); //有返回值 多个参数 LambdaReturnMutipleParam lambda6 = (int a,int b) -> { return a * b; }; System.out.println(lambda6.test(3,6));
运行结果:
无返回值 无参数!
3
30
12345
45
18
4. Lambda表达式精简?
/** * Lambda表达式语法精简 * 1. 参数类型可以省略不写; * 2. 当参数只有一个的时候,小括号可以省略 * 3. 如果方法体只有一条语句,大括号可以省略 * 如果唯一的一条语句是返回语句,则大括号 和 return应同时省略 */ public class Syntax2 { public static void main(String[] args) { LambdaReturnMutipleParam lambda = (a,b) -> a*b; LambdaReturnOneParam lambda2 = a -> a+1; System.out.println(lambda.test(4,5)); System.out.println(lambda2.test(19)); } }
5. Lambda表达式方法引用?
/** * 方法引用: * 可以快速的将一个Lambda表达式的实现指向一个已经是实现的方法. * 语法:方法的隶属者::方法名 * * 注意:参数数量、类型,返回值类型,要和接口中定义的方法一致. */ public class Syntax3 { public static void main(String[] args) { LambdaReturnOneParam lambda1 = a -> change(a); //引用了change方法的实现。 LambdaReturnOneParam lambda2 = Syntax3::change; } public static int change(int a){ return a + 2; } }
6. Lambda构造方法的引用
public class Syntax4 { public static void main(String[] args) { PersonCreater creater = () -> new Person(); //构造方法的引用: PersonCreater creater1 = Person::new; Person p = creater1.getPerson(); PersonCreater1 creater2 = Person::new; Person b = creater2.getPerson("小明",12); } } interface PersonCreater{ Person getPerson(); } interface PersonCreater1{ Person getPerson(String name,int age); }
7. Lambda表达式的应用?
7.1 集合排序
public class Exercase1 { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Coco",12)); list.add(new Person("Tina",13)); list.add(new Person("Marry",10)); list.add(new Person("Lucy",16)); list.add(new Person("Nana",8)); list.sort((p1,p2) -> p1.age - p2.age); System.out.println(list); } }
public class Exercise2 { public static void main(String[] args) { /*set内置排序,有参构造需要一个参数comparator, 所以在这里提供一个对象的比较规则。 使用lambda表达式来实现Comparator接口,并实例化一个TreeSet对象*/ //TreeSet<Person> set = new TreeSet<>((p1,p2) -> p1.age - p2.age); TreeSet<Person> set = new TreeSet<>((p1,p2) -> { if (p1.age >= p2.age){ return 1; }else { return -1; } }); set.add(new Person("Coco",12)); set.add(new Person("Tina",13)); set.add(new Person("Marry",10)); set.add(new Person("Lucy",10)); set.add(new Person("Nana",8)); System.out.println(set); } }
7.2 集合遍历
public class Exercise3 { public static void main(String[] args) { // List<Integer> list = new ArrayList<>(); Collections.addAll(list,1,2,3,4,5,6,7,8,9,0); /*将集合中的每一个元素都带入到方法accept中,构造一个Consumer对象*/ //list.forEach(System.out::println); //输出集合中所有的偶数 list.forEach(ele -> { if (ele % 2 == 0){ System.out.println(ele); } }); } }
/** * 删除几何中满足条件的元素 */ public class Exercise4 { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person("Coco",12)); list.add(new Person("Tina",13)); list.add(new Person("Marry",10)); list.add(new Person("Lucy",16)); list.add(new Person("Nana",8)); //删除年龄>10的 Iterator iterator = list.iterator(); while (iterator.hasNext()){ Person person = (Person) iterator.next(); if (person.age > 10){ iterator.remove(); } } System.out.println(list); /*Lambda实现 * 将集合中的每一个元素都带入test方法中, * 如果返回值是true,则删除这个元素,构造Predicate对象*/ list.removeIf(ele -> ele.age <= 10); System.out.println(list); } }
7.3 新建线程
/** * 开辟一条线程 * 1.继承Thread类 * 2.new Thread() Runnable接口 */ public class Exercise5 { public static void main(String[] args) { Thread t = new Thread(() -> { for (int i = 0;i < 10;i++){ System.out.println(i); } }); t.start(); } }
8. Java内置的函数式接口(我们拿过来就能用的,不用自己去定义接口)
//Predicate<T> : 参数:T,返回值:boolean // IntPredicate int -> boolean // LongPredicate long -> boolean // DoublePredicate double -> 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 int -> 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
9.闭包问题?
public class ClosureDemo { public static void main(String[] args) { } private static Supplier<Integer> getNumber(){ int num = 10; return () -> { return num; }; } }
public class ClosureDemo2 { public static void main(String[] args) { //在闭包中引用的 必须是常量,编译时候 ,会默认给个fianl int a = 101; Consumer<Integer> c = ele -> { System.out.println(ele); }; c.accept(a); } }