本文共 9631 字,大约阅读时间需要 32 分钟。
我们在写lambda表达式的时候,只需要关注两部分内容即可:参数列表和方法体
lambda表达式的基础语法:(参数)->{ 方法体};
参数部分︰方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。
方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回->:分隔参数部分和方法体部分.//第一种方式 匿名内部类 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("开始执行run方法"); } };//第二种方式 使用lambda表达式 Runnable runnable = () -> { System.out.println("开始执行run方法"); };//第三种方式 使用lambda表达式最简洁的表达式 Runnable runnable = () -> System.out.println("开始执行run方法");//第四种方式 使用lambda表达式直接作为参数传递进去 Thread thread = new Thread(() -> System.out.println("开始执行run方法")); // Thread thread = new Thread(runnable); thread.start();//开启线程
以TreeSet的排列方式为例子:
package com.zz.lamdab;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.util.Comparator;import java.util.TreeSet;public class Demo5 { public static void main(String[] args) { /* Runnable runnable = () -> System.out.println("开始执行run方法了"); Thread thread = new Thread(runnable); thread.start();*///第一种方式 匿名内部类 /* Comparatorcomparator = new Comparator () { @Override public int compare(Person o1, Person o2) { return o1.getId()-o2.getId(); } };*///第二种方式 使用lambda表达式/* Comparator comparator = (Person o1, Person o2) -> { return o1.getId() - o2.getId(); };*///第三种方式 使用lambda表达式最简洁的表达式 Comparator comparator = ( o1,o2) -> o1.getId() - o2.getId();//第四种方式 使用lambda表达式直接作为参数传递进去 TreeSet treeSet = new TreeSet (( o1,o2) -> o1.getId() - o2.getId());// TreeSet treeSet = new TreeSet (comparator); TreeSet treeSet = new TreeSet (( o1,o2) -> o1.getId() - o2.getId()); treeSet.add(new Person(3, "hh1")); treeSet.add(new Person(23, "bgfgb")); treeSet.add(new Person(4, "fse")); treeSet.add(new Person(1, "fradf")); System.out.println(treeSet); }}@Data@AllArgsConstructor@NoArgsConstructorclass Person { private Integer id; private String name;}
必须是函数式接口(只有一个抽象方法的接口)
Lamdba表达式常用来代替一个接口类型的匿名对象1.形参列表的数据类型会自动推断。如果形参列表为空,只需保留()
2.如果形参只有1个,()可以省略,只需要参数的名称即可 3.如果执行语句只有一句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有一句 4.Lambda不会生成一个单独的内部类文件函数式接口:有且仅有一个抽象方法的接口。
package com.zz.lamdab;public class Demo2 { public static void main(String[] args) { // 匿名内部类 USB usb = new USB() { @Override public void service() { System.out.println("使用upan"); } }; useUSB(usb); USB shubiao = () -> { System.out.println("使用鼠标"); }; useUSB(shubiao); } // 函数式接口的应用:作为方法的参数。调用方法时可以使用lamdba表达式 public static void useUSB(USB usb) { usb.service(); }}//函数式接口 :接口中只有一个抽象方法,该接口就是函数式接口interface USB { public void service();//服务 // jdk8之后新增的 default void show() { }}
package com.zz.lamdab;import com.sun.org.apache.bcel.internal.generic.NEW;import java.util.function.Consumer;public class Demo3 { public static void main(String[] args) { // MyConsumer consumer = new MyConsumer<>();// Demo3.fun(consumer,22.2);/* Consumerconsumer1 = new Consumer() { @Override public void accept(Object o) { System.out.println("我的美甲金额"+o); } }; Demo3.fun(consumer1,22.2);*/// Consumer consumer = (aDouble) ->System.out.println("我的美甲金额"+aDouble); Consumer consumer = aDouble -> System.out.println("我的美甲金额" + aDouble); Demo3.fun(consumer, 33.3); } public static void fun(Consumer consumer, Double param) { consumer.accept(param);//有形参无返回值 多态 }}class MyConsumer implements Consumer { @Override public void accept(Double aDouble) { System.out.println("我的消费金额" + aDouble); }}
package com.zz.lamdab;import java.util.function.Supplier;/** * @author : 小峥 * @date : 2021/4/23 22:51 * @description: */public class Demo8 { public static void main(String[] args) { // 第一种 有返回值 带return 和{} Suppliers=()-> { return "ssss";};// 第二种 有返回值 不带return 不带{} Supplier s4=()-> "ssss"; String s1 = Demo8.fun2(s); System.out.println(s1); }// Supplier 里面的方法get() 没有参数类型,有返回值 public static String fun2(Supplier supplier){ return supplier.get(); } }}
package com.zz.lamdab;import java.util.function.Function;import java.util.function.Supplier;/** * @author : 小峥 * @date : 2021/4/23 22:51 * @description: */public class Demo8 { public static void main(String[] args) { // 第一种 有返回值 带return 和{} Functionf=(e)->{ return "今天消费了"+e;};// 第二种 有返回值 不带return 不带{} Function f1=(e)->"今天消费了"+e; String s2 = Demo8.fun3(f); System.out.println(s2); }// Function 里面的方法 apply 有参数类型,有返回值 public static String fun3(Function function){ return function.apply(3.3); }}
public static void main(String[] args) { // boolean test(T t); Predicatep = (t) -> t > 18 ? true : false; boolean fun = Demo03.fun(p, 22); System.out.println(fun); } // 断言型 boolean test(T t); 有参数 返回值为boolean public static boolean fun(Predicate predicate, int age) { return predicate.test(age); }
函数引用:引用一个已经存在的方法,使其替代lambda表达式完成接口的实现.
主要有三种语法格式: 对象::实例方法名 类::静态方法名 类::实例方法名使用类名:: 方法名,不加括号
package com.zz.lamdab.lamdba03;import com.sun.org.apache.regexp.internal.RE;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.lang.reflect.Array;import java.util.Arrays;import java.util.Comparator;import java.util.Random;import java.util.UUID;public class Demo1 { public static void main(String[] args) { People[] people = new People[10]; for (int i = 0; i < 10; i++) { people[i] = new People(new Random().nextInt(100), UUID.randomUUID().toString().substring(0, 6)); }// Arrays数组的工具类 Conllection 集合的工具类// Arrays.sort(people); System.out.println(Arrays.asList(people)); Arrays.sort(people, new PeopleComparator());// lamdba表达式 System.out.println(Arrays.asList(people));// Arrays.sort(people,(a,b)-> a.getAge().compareTo(b.getAge()));// Arrays.sort(people,(a,b)->People.compare(a,b)); Arrays.sort(people, People::compare); System.out.println(Arrays.asList(people)); }}//比较器class PeopleComparator implements Comparator{ @Override public int compare(People o1, People o2) { return o1.getAge().compareTo(o2.getAge()); }}@Data@AllArgsConstructor@NoArgsConstructorclass People { private Integer age; private String name; // 比较两个对象的年龄是否一致 public static int compare(People a, People b) { return a.age.compareTo(b.age); }}
实例方法引用,顾名思义就是调用已经存在的实例的方法,与静态方法引用不同的是类要先实例化,静态方法引用类无需实例化,直接用类名去调用。
对象名::方法名,不加括号
package com.zz.lamdab.lamdba03;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.util.function.Supplier;public class Demo02 { public static void main(String[] args) { User user = new User(15,"哈哈"); Suppliersupplier=()->user.getName(); System.out.println("用户的名字:"+supplier.get());// 对象名::方法名 Supplier supplier1=user::getName; }}@Data@AllArgsConstructor@NoArgsConstructorclass User{ private Integer age; private String name;}
若Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数时,可以使用对象方法引用。
如果在使用lambda表达式,实现某些接口的时候。表达式中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整体的逻辑.其他的参数,可以作为调用方法的参数.此时,可以对这种实现进行简化。public static void main(String[] args) { // 方法引用// 可以接收两个参数,返回指针为boolean// boolean test(T t, U u);// BiPredicatepredicate=(t,u)->t.equals(u); BiPredicate predicate1=String::equals; System.out.println(predicate1.test("zz", "ee")); }
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。
public static void main(String[] args) { // 构造方法的引用// T get(); Suppliersupplier=()->new User(); Supplier supplier11=User::new; System.out.println(supplier.get());// R apply(T t, U u);// 构造方法的引用// BiFunction b=(t,u)->new User(t,u); BiFunction b=User::new; User u = b.apply(18, "峥峥"); System.out.println(u); }
转载地址:http://xvmg.baihongyu.com/