JDK中Lambda表达式的操作
这篇文章主要介绍“JDK中Lambda表达式的操作”,在日常操作中,相信很多人在JDK中Lambda表达式的操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JDK中Lambda表达式的操作”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
成都创新互联公司长期为成百上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为安宁企业提供专业的成都做网站、网站建设,安宁网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。
一、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 { Callablec1 = new Callable() { @Override public String call() throws Exception { return "muxiaonong"; } }; System.out.println(c1.call()); Callable c2 = ()->{return "muxiaonong2";}; System.out.println(c2.call()); //逻辑很简单的时候省略 {} 和 return Callable c3 = ()->"muxiaonong3"; System.out.println(c3.call()); }
二、Lambda表达式的特点
函数式编程
参数类型自动推断
代码量少,简洁
三、Lambda表达式案例
实现方式列表:
()->{} ()->{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) { Listlist = Arrays.asList("java","python","scala","javascript"); //普通匿名内部类方式 Collections.sort(list, new Comparator () { @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); }
四、Lambda表达式的应用场景
重要的事情说三遍:任何有函数式接口的地方 * 3
什么是函数式接口: 只有一个抽象方法(Object类中的方法除外)的接口是函数式接口
五、Lambda表达式实际应用
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:代表一个输出
Suppliers1 = ()->{return "muxiaonong";}; Supplier s2 = ()->"muxiaonong2"; System.out.println(s1.get());//输出 muxiaonong System.out.println(s2.get());//输出 muxiaonong2
6.2 Consumer:代表一个输入
Consumerc11 = (str) -> System.out.println(str); c11.accept("beijing");//输出 beijing
6.3 BiConsumer:代表两个输入
BiFunctionbf = (a,b)->a.length()+b.length(); System.out.println(bf.apply("大吉大利", "今晚吃鸡"));//输出一个字符串长度 8
6.4 Function:代表一个输入,一个输出
// Function用来接收后面的函数的实现,规定必须有一个输入(String)有一个输出(Integer) Function 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 //无参静态方法-原生调用 Suppliers1 = ()-> Test2.put(); System.out.println(s1.get());//输出put //无参静态方法-静态方法引用 Supplier s2 = Test2::put; System.out.println(s2.get());//输出put //无参静态方法-内部类调用 Supplier s3 = Fun::hehe; System.out.println(s3.get()); //输出hehe // 有参静态方法-静态方法引用 Consumer c1 = Test2::getSize; Consumer c2 = (size)-> Test2.getSize(size); c1.accept(123); c2.accept(111); //有参有返回值静态方法 Function f1 = (str)->str.toUpperCase(); Function f2 = (str)-> Test2.toUpperCase(str); Function f3 = Test2::toUpperCase; Function 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 bf = (a, b)->a.length()+b.length(); BiFunction 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... Suppliers1 = ()->new Test3().put(); Supplier s2 = ()->{return new Test3().put();}; Supplier 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 c1 = (size)->new Test3().getSize(size); Consumer c2 = new Test3()::getSize; Consumer c3 = test::getSize; c1.accept(123);//输出 size:123 c2.accept(123);//输出 size:123 c3.accept(123);//输出 size:123 Function f1 = (str)->str.toUpperCase(); Function f2 = (str)->test.toUpperCase(str); Function f3 = new Test3()::toUpperCase; Function 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) { Consumerc1 = (too)->new Too().foo(); c1.accept(new Too());//输出 foo Consumer c2 = (Too too) ->new Too2().foo(); c2.accept(new Too());//输出 foo---too2 Consumer c3 = Too::foo; c3.accept(new Too());//输出 foo BiConsumer bc = (too2,str)->new Too2().show(str); BiConsumer bc2 = Too2::show; bc.accept(new Too2(),"abc"); bc2.accept(new Too2(),"def"); BiFunction bf1 = (e,s)->new Exec().test(s); bf1.apply(new Exec(),"abc"); BiFunction 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) { Suppliers1 = ()->new Person(); s1.get();//输出 调用无参的构造方法 Supplier s2 = Person::new; s2.get();//输出 调用无参的构造方法 Supplier s3 = ArrayList::new; Supplier
s4 = HashSet::new; Supplier s5 = Thread::new; Supplier s6 = String::new; Consumer c1 = (age)->new Account(age); Consumer c2 = Account::new; c1.accept(123);// 输出 age 参数构造123 c2.accept(456);//输出 age 参数构造456 Function f1 = (str)->new Account(str); Function 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表达式的操作”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
本文题目:JDK中Lambda表达式的操作
分享路径:http://azwzsj.com/article/ijispp.html