博客
关于我
lambda01(JDK8.之后出现很多新特性), 函数式接口
阅读量:386 次
发布时间:2019-03-05

本文共 9631 字,大约阅读时间需要 32 分钟。

lambda01(JDK8.之后出现很多新特性), 函数式接口

lambda

我们在写lambda表达式的时候,只需要关注两部分内容即可:参数列表和方法体

lambda表达式的基础语法:

(参数)->{   方法体};

参数部分︰方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。

方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回->:分隔参数部分和方法体部分.
在这里插入图片描述
以线程为例子(以下有3种方式):

//第一种方式  匿名内部类        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();*///第一种方式  匿名内部类   /*     Comparator
comparator = 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不会生成一个单独的内部类文件
在这里插入图片描述

函数式接口

函数式接口:有且仅有一个抽象方法的接口。

在这里插入图片描述
在这里插入图片描述

常见的函数式接口

在这里插入图片描述

函数式接口USB代码:

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() {       }}

常见接口代码测试

Consumer代码测试

在这里插入图片描述

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);/*        Consumer
consumer1 = 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); }}

Supplier代码测试

在这里插入图片描述

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  和{}            Supplier
s=()-> { 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(); } }}

Function代码测试

在这里插入图片描述

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  和{}        Function
f=(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); }}

Predicate代码测试

在这里插入图片描述

public static void main(String[] args) {   //         boolean test(T t);        Predicate
p = (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,"哈哈");        Supplier
supplier=()->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);//        BiPredicate
predicate=(t,u)->t.equals(u); BiPredicate
predicate1=String::equals; System.out.println(predicate1.test("zz", "ee")); }

String的equals()方法:

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();        Supplier
supplier=()->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/

你可能感兴趣的文章
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>