这篇文章主要介绍“JDK中Lambda表达式的操作”,在日常操作中,相信很多人在JDK中Lambda表达式的操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JDK中Lambda表达式的操作”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Lambda表达式是 Java8 中最重要的新功能之一。使用 Lambda 表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。
lambda表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂
lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作
lambda可以极大的减少代码冗余,同时代码的可读性要好过冗长的内部类,匿名类
例如以前我们使用匿名内部类来实现代码:
Runnable runnable = new Runnable() { @Override public void run() { System.out.println("running1 ....."); } }; runnable.run();
使用lambda表达式实现更简洁的代码:
Runnable runnable3 = ()-> System.out.println("running2...."); runnable3.run();
lambda表达式语法:
LambdaParameters -> LambdaBody
在这里插入图片描述
args -> expr或者(object … args)-> {函数式接口抽象方法实现逻辑}
1、()参数的个数,根据函数式接口里面抽象的参数个数来决定,当参数只有一个的时候,()可以省略
2、当expr逻辑非常简单的时候,{}和return可以省略
案例说明:
public static void main(String[] args) throws Exception { Callable<String> c1 = new Callable() { @Override public String call() throws Exception { return "muxiaonong"; } }; System.out.println(c1.call()); Callable<String> c2 = ()->{return "muxiaonong2";}; System.out.println(c2.call()); //逻辑很简单的时候省略 {} 和 return Callable<String> c3 = ()->"muxiaonong3"; System.out.println(c3.call()); }
函数式编程
参数类型自动推断
代码量少,简洁
实现方式列表:
()->{} ()->{System.out.println(1);} ()->System.out.println(1) ()->{return 100;} ()->100 ()->null (int x)->{return x+1;} (int x)->x+1 (x)->x+1 x->x+1
案例1:线程实现方式:
public static void main(String[] args) { //匿名内部类方式 new Thread(new Runnable() { @Override public void run() { System.out.println("runing1.........."); } }); //Lambda表达式方式 new Thread(() -> {System.out.println("runing2.....");}).start(); }
案例2:集合遍历实现方式
public static void main(String[] args) { List<String> list = Arrays.asList("java","python","scala","javascript"); //普通匿名内部类方式 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }); //Lambda方式 Collections.sort(list,(a,b) -> a.length() - b.length()); list.forEach(System.out::println); }
重要的事情说三遍:任何有函数式接口的地方 * 3
什么是函数式接口: 只有一个抽象方法(Object类中的方法除外)的接口是函数式接口
5.1 无参实体类模拟
模拟数据库连接层:
@FunctionalInterface public interface StudentDao { void insert(Student student); }
实体类
/** @Author mxn * @Description 学生实体类 * @Date 10:19 2020/11/7 * @Param * @return **/ public class Student { } public static void main(String[] args) { StudentDao sd1 = new StudentDao() { @Override public void insert(Student student) { System.out.println("插入学生1"); } }; StudentDao sd2 = (student)->{ System.out.println("student: "+student); }; StudentDao sd3 = (Student student)-> System.out.println("student3:"+student); sd1.insert(new Student()); //输出 插入学生1 sd2.insert(new Student());// 输出 sd3.insert(new Student());// 输出 }
5.2 有参实体类模拟
实体类
/** @Author mxn * @Description * @Date 10:26 2020/11/7 * @Param * @return **/ public class Teacher { }
接口模拟层
@FunctionalInterface public interface TeacherDao { int get(Teacher teacher); }
实现层
public static void main(String[] args) { TeacherDao td1 = new TeacherDao() { @Override public int get(Teacher teacher) { return 1; } }; TeacherDao td2 = (teacher)->{return 2;}; TeacherDao td3 = (Teacher teacher)->{return 3;}; TeacherDao td4 = (teacher)->4; TeacherDao td5 = (Teacher teacher)->5; System.out.println(td1.get(new Teacher()));//输出 1 System.out.println(td2.get(new Teacher()));//输出 2 System.out.println(td3.get(new Teacher()));//输出 3 System.out.println(td4.get(new Teacher()));//输出 4 System.out.println(td5.get(new Teacher()));//输出 5 }
Supplier:代表一个输出
Consumer:代表一个输入
BiConsumer:代表两个输入
Function:代表一个输入,一个输出(一般输入和输出是不同类型的)
UnaryOperator:代表一个输入,一个输出(输入和输出是相同类型的)
BiFunction:代表两个输入,一个输出(一般输入和输出是不同类型的)
BinaryOperator:代表两个输入,一个输出(输入和输出是相同类型的)
在Java中提供了一系列的函数式接口,用来接受后续传入的逻辑,但是对输入和输出有要求
6.1 Supplier:代表一个输出
Supplier<String> s1 = ()->{return "muxiaonong";}; Supplier<String> s2 = ()->"muxiaonong2"; System.out.println(s1.get());//输出 muxiaonong System.out.println(s2.get());//输出 muxiaonong2
6.2 Consumer:代表一个输入
Consumer<String> c11 = (str) -> System.out.println(str); c11.accept("beijing");//输出 beijing
6.3 BiConsumer:代表两个输入
BiFunction<String,String,Integer> bf = (a,b)->a.length()+b.length(); System.out.println(bf.apply("大吉大利", "今晚吃鸡"));//输出一个字符串长度 8
6.4 Function:代表一个输入,一个输出
// Function<String,Integer> 用来接收后面的函数的实现,规定必须有一个输入(String)有一个输出(Integer) Function<String,Integer> f1 = (str)->{return str.length();}; System.out.println(f1.apply("abcdefg"));//输出长度 7
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用
7.1 方法引用的分类
7.2 静态方法引用
静态方法引用: 如果函数式接口的实现恰好可以通过 调用一个静态方法 来实现,那么就可以使用静态方法引用
/** * @program: lambda * @ClassName Test2 * @description: * @author: muxiaonong * @create: 2020-10-28 22:15 * @Version 1.0 **/ public class Test2 { //无参静态方法 static String put(){ System.out.println("put....."); return "put"; } //有参静态方法 public static void getSize(int size){ System.out.println(size); } //有参 有返回值静态方法 public static String toUpperCase(String str){ return str.toUpperCase(); } //两个入参,一个返回值静态方法 public static Integer getLength(String str,String str2){ return str.length()+str2.length(); } public static void main(String[] args) { //无参静态方法-普通调用 System.out.println(put());//输出put //无参静态方法-原生调用 Supplier<String> s1 = ()-> Test2.put(); System.out.println(s1.get());//输出put //无参静态方法-静态方法引用 Supplier<String> s2 = Test2::put; System.out.println(s2.get());//输出put //无参静态方法-内部类调用 Supplier<String> s3 = Fun::hehe; System.out.println(s3.get()); //输出hehe // 有参静态方法-静态方法引用 Consumer<Integer> c1 = Test2::getSize; Consumer<Integer> c2 = (size)-> Test2.getSize(size); c1.accept(123); c2.accept(111); //有参有返回值静态方法 Function<String,String> f1 = (str)->str.toUpperCase(); Function<String,String> f2 = (str)-> Test2.toUpperCase(str); Function<String,String> f3 = Test2::toUpperCase; Function<String,String> f4 = Test2::toUpperCase; System.out.println(f1.apply("abc"));//输出 ABC System.out.println(f2.apply("abc"));//输出 ABC System.out.println(f3.apply("abc"));//输出 ABC System.out.println(f4.apply("abc"));//输出 ABC // 两个参数 一个返回值 函数式接口 BiFunction<String,String,Integer> bf = (a, b)->a.length()+b.length(); BiFunction<String,String,Integer> bf2 = Test2::getLength; System.out.println(bf2.apply("abc", "def"));//输出 6 System.out.println(bf.apply("abc", "def"));//输出 6 } //内部类 class Fun { public static String hehe(){ return "hehe"; } public static String toUpperCase(String str){ return str.toUpperCase(); } } }
7.3 实例方法引用
实例方法引用: 如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
public class Test3 { //实例无参方法 public String put(){ return "put..."; } //实例有参方法 public void getSize(int size){ System.out.println("size:"+size); } //实例有参有返回值方法 public String toUpperCase(String str){ return str.toUpperCase(); } public static void main(String[] args) { //实例无参方法返回-普通调用 System.out.println(new Test3().put());//输出 put... Supplier<String> s1 = ()->new Test3().put(); Supplier<String> s2 = ()->{return new Test3().put();}; Supplier<String> s3 = new Test3()::put; System.out.println(s1.get());//输出 put... System.out.println(s2.get());//输出 put... System.out.println(s3.get());//输出 put... //唯一的创建一个test3对象 Test3 test = new Test3(); Consumer<Integer> c1 = (size)->new Test3().getSize(size); Consumer<Integer> c2 = new Test3()::getSize; Consumer<Integer> c3 = test::getSize; c1.accept(123);//输出 size:123 c2.accept(123);//输出 size:123 c3.accept(123);//输出 size:123 Function<String,String> f1 = (str)->str.toUpperCase(); Function<String,String> f2 = (str)->test.toUpperCase(str); Function<String,String> f3 = new Test3()::toUpperCase; Function<String,String> f4 = test::toUpperCase; System.out.println(f1.apply("abc"));//输出 ABC System.out.println(f2.apply("abc"));//输出 ABC System.out.println(f3.apply("abc"));//输出 ABC System.out.println(f4.apply("abc"));//输出 ABC } }
7.4 对象方法引用
对象方法引用: 抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
/** @Author mxn * @Description //TODO 对象方法引用 * @Date 14:26 2020/11/7 * @Param * @return **/ public class Test4 { public static void main(String[] args) { Consumer<Too> c1 = (too)->new Too().foo(); c1.accept(new Too());//输出 foo Consumer<Too> c2 = (Too too) ->new Too2().foo(); c2.accept(new Too());//输出 foo---too2 Consumer<Too> c3 = Too::foo; c3.accept(new Too());//输出 foo BiConsumer<Too2,String> bc = (too2,str)->new Too2().show(str); BiConsumer<Too2,String> bc2 = Too2::show; bc.accept(new Too2(),"abc"); bc2.accept(new Too2(),"def"); BiFunction<Exec,String,Integer> bf1 = (e,s)->new Exec().test(s); bf1.apply(new Exec(),"abc"); BiFunction<Exec,String,Integer> bf2 = Exec::test; bf2.apply(new Exec(),"def"); } } class Exec{ public int test(String name){ return 1; } } class Too{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo"); } } class Too2{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo---too2"); } public void show(String str){ System.out.println("show ---too2"+str); } }
7.5 构造方法引用
构造方法引用: 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
/** @Author mxn * @Description //TODO 构造方法引用 * @Date 14:27 2020/11/7 * @Param * @return **/ public class Test5 { public static void main(String[] args) { Supplier<Person> s1 = ()->new Person(); s1.get();//输出 调用无参的构造方法 Supplier<Person> s2 = Person::new; s2.get();//输出 调用无参的构造方法 Supplier<List> s3 = ArrayList::new; Supplier<Set> s4 = HashSet::new; Supplier<Thread> s5 = Thread::new; Supplier<String> s6 = String::new; Consumer<Integer> c1 = (age)->new Account(age); Consumer<Integer> c2 = Account::new; c1.accept(123);// 输出 age 参数构造123 c2.accept(456);//输出 age 参数构造456 Function<String,Account> f1 = (str)->new Account(str); Function<String,Account> f2 = Account::new; f1.apply("abc");//输出 str 参数构造abc f2.apply("def");//输出 str 参数构造def } } class Account{ public Account(){ System.out.println("调用无参构造方法"); } public Account(int age){ System.out.println("age 参数构造" +age); } public Account(String str){ System.out.println("str 参数构造" +str); } } class Person{ public Person(){ System.out.println("调用无参的构造方法"); } }
到此,关于“JDK中Lambda表达式的操作”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。