java8-Lambda表达式介绍

简介

 Lambda,“语法糖”,是一个匿名函数,我们可以把Lambda表达式理解为是一个可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使java的语言表达能力得到了提升。

为什么使用Lambda表达式

 可以以下代码

@Test
    public void test4(){
    	//使用匿名内部类
        Comparator<Integer> comparator = new Comparator<>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        System.out.println(comparator.compare(2,3));
        System.out.println("----------------------------------------");
        //使用Lambda表达式
        Comparator<Integer> handler = (x, y) -> Integer.compare(x, y);
        System.out.println( handler.compare(2,3));
    }

输出

-1
----------------------------------------
-1

从以上代码可以看出不使用Lambda表达式时,代码非常的繁琐,随着回调模式和函数式编程风格的日益流行,我们需要在Java中提供一种尽可能轻量级的将代码封装为数据的方法。匿名内部类并不是一个好的选择,因为:
 1. 语法过于冗余
 2. 匿名内部类中this和变量名容易使人产生误解
 3. 类型载入和实例创建语义不够灵活
java8解决了这些问题
因此你可以使用更少的代码来实现同样的功能。

Lambda表达式的基础语法

概念

 在Java8中引入了一个新的操作符“->” 称作箭头操作符或Lambda表达式。
Lambda分为两个部分

  • 左侧:Lambda表达式的参数列表
  • 右侧:Lambda表达式中所需执行的功能,即Lambda体

语法格式

  1. 无参数吗,无返回值
()->System.out.println("hello world!");
  1. 有参数,并且无返回值
(x)->System.out.println(x);
  1. 若只有一个参数,则小括号可以省略不写
x->System.out.println(x);
  1. 有两个以上的参数,有返回值,并且Lambda体中有多条语句时
Comparator<Integer> con = (x,y)->{
		System.out.println("函数式接口");
		return Integer.compare(x,y);
}
  1. 若Lambda表达式中只有一条语句时
Comparator<Integer> com =(x,y)->Integer.compare(x,y);
  1. Lambda 表达式的参数列表的参数类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即类型推断
Comparator<Integer> com=(Integer x,Integer y)->Integer.compare(x,y);
Comparator<Integer> com=(x,y)->Integer.compare(x,y);

注意

Lambda表达式需要“函数式接口”的支持
函数式接口:接口中只有一个抽象方法的接口称为函数式接口,可以使用注解@FunctionalInterface来修饰,可以检查是否是函数式接口

Java8内置的四大核心函数式接口

介绍

函数式接口说明参数类型返回类型内置方法用途
Consumer消费型接口Tvoidvoid accept(T t)对类型T参数操作,无返回结果。
Supplier供给型接口TT get()返回T类型参数。
Function函数型接口TRR apply(T t)对于类型T参数操作,返回R类型参数。
Predicate断言型接口Tbooleanboolean test(T t)对类型T进行条件筛选操作,返回boolean.
  1. Consumer 消费型接口
    /**
     * Consumer<T> 消费者类型接口 无返回值
     */
    @Test
    public void consumer(){
        consumers("张三", new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s+"去了北京天安门");
            }
        });
        System.out.println("--------Lambda表达式--------");
        consumers("李四",n-> System.out.println(n+"去了九寨沟"));
    }

    void consumers(String Name,Consumer<String> con){
        con.accept(Name);
    }
    ------------------输出------------------
    张三去了北京天安门
	--------Lambda表达式--------
	李四去了九寨沟
  1. Supplier 供给型接口
    /**
     * Supplier 供给型接口 T get();
     */
    @Test
    public void supplier(){
        List<Integer> list1 = getNumList(5, new Supplier<Integer>() {
            @Override
            public Integer get() {
                return (int) (Math.random() * 10);
            }
        });
        list1.forEach(System.out::println);
        System.out.println("--------Lambda表达式--------");
        List<Integer> list = getNumList(5,()->(int)(Math.random()*100));
        list.forEach(System.out::println);
    }

    List<Integer> getNumList(int num , Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for (int i=0; i<num; i++){
            Integer n = sup.get();
            list.add(n);
        }
        return list;
    }
    -----------------输出------------------
    3
	3
	0
	1
	8
	--------Lambda表达式--------
	21
	5
	92
	69
	69
    
  1. Function 函数型接口
    /**
     * Function<T,R>  函数型接口 R apply(T t);
     */
    @Test
    public void function(){
        String s = handle("hjkwegfkGHJKjksagdhfjklgwhejf", new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase();
            }
        });
        System.out.println(s);
        System.out.println("--------Lambda表达式--------");
        String s2 = handle("hdjagshjgquga", s1 -> s1.toUpperCase());
        System.out.println(s2);
    }

    String handle(String str, Function<String,String> f){
        return f.apply(str);
    }
    --------------输出--------------------
    HJKWEGFKGHJKJKSAGDHFJKLGWHEJF
	--------Lambda表达式--------
	HDJAGSHJGQUGA
  1. Predicate 断言型接口
    /**
     * Predicate 断言型接口 boolean test(T t)
     */
    @Test
    public void predicate(){
        List<Integer> list = Arrays.asList(10, 9, 20, 31, 21, 42);
        //如果数大于18就加入新的集合中
        List<Integer> filter = filter(list, new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer > 18;
            }
        });
        filter.forEach(System.out::println);
        System.out.println("--------Lambda表达式--------");
        List<Integer> f = filter(list, x -> x > 18);
        f.forEach(System.out::println);
    }

    List<Integer> filter(List<Integer> list, Predicate<Integer> p){
        List<Integer> list1 = new ArrayList<>();
        for (Integer integer : list) {
            if(p.test(integer)){
               list1.add(integer);
            }
        }
        return list1;
    }
    -----------------------输出-----------------
    20
	31
	21
	42
	--------Lambda表达式--------
	20
	31
	21
	42

其他延申函数式接口

函数式接口参数类型返回类型内置方法用途
BiFunctionT,URR apply(T t,U u)对类型T,U参数进行操作,返回R类型结果
UnaryOperatorTTT apply(T t)对类型T对象进行一元运算,并返回T类型的结果
BinaryOperatorT,TTT apply(T t1,T t2)对类型T对象进行二元运算,并返回T类型的结果
BiConsumerT,Uvoidvoid accept(T t,U u)对类型T,U参数进行操作
ToIntFunction /ToLongFunction / ToDoubleFuctionTint,long,doubleint applyAsInt(T value)/ long applyAsLong(T value) /double applyAsDouble(T value)分别计算int,long,double值
IntFunction /LongFunction / DoubleFuctionint,long,doubleRR apply(int value)/R apply(longvalue) /R apply(double value)参数分别是int,long,double类型函数

方法引用

 若Lambda体中的功能已经有方法提供了实现,可以使用方法引用(可以将方法引用理解为Lambda表达式的另外一种表现形式)

基本的引用

  1. 对象::实例方法
User u =new User();
u::getName
  1. 类名::静态方法名
Comparator<Integer> handler = Integer::compare;
  1. 类名::实例方法名
User::getName

注意

  1. 方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中的抽象方法的参数列表和返回值保持一致
  2. 若Lambda的参数列表的第一参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式为ClassName::MethodName

扩展

  1. 构造器引用
    构造器的参数列表需要与函数式接口中的参数列表保持一致
    类名::new
User::new 
  1. 数组引用
    类型[]::new
Integer[]::new 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值