Java 8 的lambda表达式

本文介绍了Java8中引入的Lambda表达式,一种新的代码编写方式,使得代码更加简洁高效。文章通过对比不同版本的代码展示了Lambda表达式的优点,并解释了其基本语法和使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java 8的lambda表达式

众所知周,java是一个面向对象的语言,除了部分的简单数据类型,在java中的一切都是以对象的形式存在,即使数组也是一种对象,每个类创建的实例也都是对象。在Java中定义的函数或方法是不可能完全独立的,也不能将方法作为参数或返回一个方法的实例。

而在java8之前,如若我们想要把某些功能传递给某个方法去,就是要去写一个匿名的内部类。

在java的发展过程当中,对功能的传递有着以下的方式

package com.wang.javaforword.lambda;

import java.util.Arrays;
import java.util.Comparator;

//lambda 诞生的背景
//java中的方法都是包含在对象当中,不能独立的当做参数传递
public class Demo {
    public static void main(String[] args) {
        String[] arr = {"b", "c", "a", "d"};
        Arrays.sort(arr);       //本身是升序的排列方式
        System.out.println(Arrays.toString(arr));
    }
}

在这里插入图片描述默认的情况下是按照一个升序的方式进行排列的

那么我们现在想将这个排列的方式改为一降序的方式进行排列。就要写一个方法,进过这个方法对排序的方式进行改变。

package com.wang.javaforword.lambda;

import java.util.Arrays;
import java.util.Comparator;

//lambda 诞生的背景
//java中的方法都是包含在对象当中,不能独立的当做参数传递
public class Demo {
    public static void main(String[] args) {
        String[] arr = {"b", "c", "a", "d"};
        Arrays.sort(arr,new StringCom());       
        //可以创进来一个比较器,自定义的一种排序比较
        System.out.println(Arrays.toString(arr));
    }
}
package com.wang.javaforword.lambda;

import java.util.Comparator;

/*创建一个字符串排序的一个类*/
public class StringCom implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        return o2.compareTo(o1);//降序比
    }
}

在这里插入图片描述
因为只需要在这个地方需要这么一个比较器,所以我们就可以将它写为一个内部类的形式。

package com.wang.javaforword.lambda;

import java.util.Arrays;
import java.util.Comparator;

//lambda 诞生的背景
//java中的方法都是包含在对象当中,不能独立的当做参数传递
public class Demo {
    public static void main(String[] args) {
        String[] arr = {"b", "c", "a", "d"};
        Arrays.sort(arr,new StringCom1());
        System.out.println(Arrays.toString(arr));
    }

    //创建一个内部类的一个东西,就不需要在外部创建一个类
    static class StringCom1 implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            return o2.compareTo(o1);
        }
    }
}

在这里插入图片描述
再经过发展,我们可以将其写成一个匿名的内部类形式。

package com.wang.javaforword.lambda;

import java.util.Arrays;
import java.util.Comparator;

//lambda 诞生的背景
//java中的方法都是包含在对象当中,不能独立的当做参数传递
public class Demo {
    public static void main(String[] args) {
        String[] arr = {"b", "c", "a", "d"};
        
        //匿名内部类 new + 接口/抽象类 创建一个匿名内部类的对象
        Arrays.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.compareTo(o1);
            }
        });
        System.out.println(Arrays.toString(arr));
    }
}

在这里插入图片描述在之上的例子中,为了对数组(集合)进行排序,我们为Comparator接口创建一个它的匿名内部类对象,重写接口中的方法,来实现排序的功能。

简而言之,在java中将普通的方法或函数像参数一样传递是并不简单的,为此,在java8之后中,增加了一个语言级的新特性,名为lambda的表达式。

什么是lambda的表达式

lambda表达式是一个匿名的函数,我们可以把lambda表达式理解为一段可以传递的代码(将代码看作是参数一样进行传递)。
使用它可以让我们写出更为简洁、灵活的代码。作为一种更紧凑的代码风格,使java语言的表达能力得到很大的提升。

lambda表达式的本质上只是一个 “语法糖”,有编译器推断并帮助你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。

语法糖: 也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

lambda的一些简单语法

java中的lambda表达式通常使用 (argument) -> {body}
(参数)->{ 函数体 }
左侧:lambda 表达式的参数列表
右侧:lambda 表达式中需要执行的功能,即 lambda 体

(arg1, arg2…) -> { body }
(type1 arg1, type2 arg2…) -> { body }
表达式参数类型是可以不写,jvm 可以根据上下文进行类型推断

以下就是一些lambda表达式的例子:

  1. 无参数,无返回值,lambda 体中只有一行代码时,{}可以忽略
    ( ) -> System.out.println ( “Hello World” );
  2. 无参数,有返回值
    () -> { return 3.1415 };
  3. 有参数,无返回值
    (String s) -> { System.out.println(s); }
  4. 有一个参数,无返回值
    s -> { System.out.println(s); }
  5. 有多个参数,有返回值
    (int a, int b) -> { return a + b; }
  6. 有多个参数,表达式参数类型可以不写,jvm 可以根据上下文进行类型推断
    (a, b) -> { return a - b; }

lambda表达式的结构

● lambda表达式可以具有零个,一个或多个参数。
● 可以显示声明参数的类型,也可以由编译器自动从上下文推断参数的类型。Lambda表达式会帮助我们推断出这个参数的类型。
例如(int a,int b)就可以写成(a,b)
● 参数用小括号括起来,用逗号分隔。例如 (a, b) 、 (int a, int b) 或 (String a, int b, float c)构成。
● 空括号用于表示一组空的参数。例如 () -> 42。
● 当有且仅有一个参数时,如果不显式指明类型,则不必使用小括号。
例如 a -> return a*a。
● Lambda 表达式的正文可以包含零条,一条或多条语句。
● 如果 Lambda 表达式的正文只有一条语句,则大括号可不用写,且表达式 的返回值类型要与匿名函数的返回类型相同。
● 如果 Lambda 表达式的正文有一条以上的语句必须包含在大括号(代码块) 中,且表达式的返回值类型要与匿名函数的返回类型相同。

Lambda表达式中的正文实现的接口中只能有一个抽象方法。(因为它省略的匿名内部类中的方法名)

功能接口(Functional interface)

在这里插入图片描述在有些接口类中,会有@FunctionalInterface这个标签的存在,是功能接口的意思。

功能接口是 java 8 中的新增功能,加上这个标签就意思为在这个接口中,只能有一个抽象方法,如果出现两个以上的话,就会在编译的时候就会报错。这些接口也称为单抽象方法接口。

这些也可以使用 Lambda 表达式,方法引用和构造函数引用来表示。Java 8 也引入了一个注释,即@FunctionalInterface,当你注释的接口违反了 Functional Interface 的契约时,它可以用于编译器级错误。

一般情况在接口上看到写有@FunctionalInterface,表示这个接口是为lambda打造的

Lambda中的核心思想就是将接口中的函数当做参数一样进行传递。(在使用Lambda的时候有要求到这个接口中的抽象方法只有一个)

Lambda 表达式的例子

  1. 线程初始化
    ● 匿名内部类方式
        new Thread(new Runnable() {
            @Override
            public void run() {

            }
        });

● Lambda 表达式方式

        new Thread(()->{
            System.out.println("apple");
        });
  1. 事件处理
    ● 匿名内部类方式
        JButton jButton = new JButton("按钮");
        
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

            }
        });

● Lambda 表达式方式

        JButton jButton = new JButton("按钮");
         
        jButton.addActionListener((e -> {
            System.out.println("demo");
        }));
  1. 遍历输出
    输出给定数组的所有元素的简单代码。请注意,还有一种使用 Lambda 表达式的方式。
    ● 普通方式
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
        for (Integer n : list) {
            System.out.println(n);
        }

● 使用 -> 的 Lambda 表达式

		list.forEach(n -> System.out.println(n));

下一篇----> Java8 Stream的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值