09Java第九章lambda表达式

Java8引入的Lambda表达式使得将方法作为参数传递变得简单,它是一种匿名函数,可以理解为可传递的代码片段。在示例中,展示了在排序操作中如何使用Lambda替代传统的Comparator实现,简化了代码并提高了可读性。Lambda的基本语法包括参数列表、箭头符号及函数体,支持零个、一个或多个参数,以及有或无返回值的情况。Lambda表达式主要用于函数式接口,是Java8的重要特性之一。

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

lambda出现的背景

Java 是一流的面向对象语言,除了部分简单数据类型,Java 中的一切都是 对象,即使数组也是一种对象,每个类创建的实例也是对象。在 Java 中定义的函数或方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例。在 Java 8 以前,若我们想要把某些功能传递给某个方法,总要去写匿名类。

简而言之,在 Java 里将普通的方法或函数像参数一样传值并不简单,为此,Java 8 增加了一个语言级的新特性,名为 Lambda 表达式。

lambda表达式简介

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

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

public class Student {
    private int no;
    private String name;

    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
    
    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Demo {
    /*
      lambda表达式是匿名函数(独立的)
    */
    public static void main(String[] args) {
        Student s1 = new Student(101, "jim1");
        Student s2 = new Student(102, "jim2");
        Student s3 = new Student(103, "jim3");
        Student s4 = new Student(104, "jim4");
        Student s5 = new Student(105, "jim5");

        ArrayList<Student> students = new ArrayList<>();
        students.add(s2);
        students.add(s3);
        students.add(s1);
        students.add(s5);
        students.add(s4);
        System.out.println(students);//按照23154存储内容输出
    }
}
  • students.sort(); Arrays.sort(); Collections.sort();
    sort方法中传入Comparator<? super E> c

  • Comparator是一个排序比较接口,里面定义了一个比较的方法,但是没有实现。
    有4种做法:
    1.写一个Comparator接口的实现类(单独的类,此类只用于学生排序)

    /*
       自定义一个学生排序类,实现sort方法中的接口
    */
    public class StudentComparator implements Comparator<Student> {
        @Override
        public int compare(Student o1, Student o2) {
            return o1.getNo()-o2.getNo();
        }
    }
    
    public class Demo {
        public static void main(String[] args) {
            Student s1 = new Student(101, "jim1");
            Student s2 = new Student(102, "jim2");
            Student s3 = new Student(103, "jim3");
            Student s4 = new Student(104, "jim4");
            Student s5 = new Student(105, "jim5");
    
            ArrayList<Student> students = new ArrayList<>();
            students.add(s2);
            students.add(s3);
            students.add(s1);
            students.add(s5);
            students.add(s4);
            students.sort(new StudentComparator()); //对其进行排序
            System.out.println(students); //按顺序输出
        }
    }
    

    2.将学生排序的功能写成一个内部类,将功能封装在类的内部,内部类也是需要定义一个类的。

    /*
      这叫一个.java文件中,写了两个类
    */
    class Demo1{
        
    }
    class Demo2{
        
    }
    
    public class Demo {
        public static void main(String[] args) {
            Student s1 = new Student(101, "jim1");
            Student s2 = new Student(102, "jim2");
            Student s3 = new Student(103, "jim3");
            Student s4 = new Student(104, "jim4");
            Student s5 = new Student(105, "jim5");
    
            ArrayList<Student> students = new ArrayList<>();
            students.add(s2);
            students.add(s3);
            students.add(s1);
            students.add(s5);
            students.add(s4);
            students.sort(new StudentComparator());
            System.out.println(students);
        }
        /*
          内部类也是属于外部类的成员,也需要是静态的
        */
        static class StudentComparator implements Comparator<Student> {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getNo()- o2.getNo();
            }
        }
    }
    

    3.在内部类的基础上,为了进一步的简化语法,java中推出了匿名内部类。

    new + 接口名/抽象类名 都不是在创建接口/抽象类对象,是在创建一个匿名的类的对象,有一个匿名的类实现了此接口。

    外部类、内部类、匿名内部类,核心都是对排序比较的方法进行实现,将方法包装在一个对象中,传递给
    了sort()方法。

    public class Demo {
        public static void main(String[] args) {
            Student s1 = new Student(101, "jim1");
            Student s2 = new Student(102, "jim2");
            Student s3 = new Student(103, "jim3");
            Student s4 = new Student(104, "jim4");
            Student s5 = new Student(105, "jim5");
    
            ArrayList<Student> students = new ArrayList<>();
            students.add(s2);
            students.add(s3);
            students.add(s1);
            students.add(s5);
            students.add(s4);
            
            students.sort(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o1.getNo()- o2.getNo();
                }
            });
            
            System.out.println(students);
        }
    }
    

    4.java8之后,对匿名内部类的写法进行了简化,可以将函数直接作为参数传递。

    public class Demo {
        /*
          lambda表达式是匿名函数(独立的)
        */
        public static void main(String[] args) {
            Student s1 = new Student(101, "jim1");
            Student s2 = new Student(102, "jim2");
            Student s3 = new Student(103, "jim3");
            Student s4 = new Student(104, "jim4");
            Student s5 = new Student(105, "jim5");
    
            ArrayList<Student> students = new ArrayList<>();
            students.add(s2);
            students.add(s3);
            students.add(s1);
            students.add(s5);
            students.add(s4);
            //lambda表达式
            students.sort((o1,o2)->{return o1.getNo()- o2.getNo(); });
            //上式等同于下式
            //常规代码
            Comparator<Student> c = (o1,o2)->{
                return o1.getNo()- o2.getNo();
            };
            students.sort(c);
            System.out.println(students);
        }
    
    }
    

lambda的基本语法

最简答的lambda表达式,没有方法也没有返回值。

使用lambda 要求是接口/抽象类中只能有一个抽象的方法,用于类型推断。

()参数列表 ->{ } 函数体

无参:

@FunctionalInterface //修饰的是功能接口,其中只能有一个抽象方法
public interface LambdaInterface {
    public abstract void test();
    public static void  testStatic(int a ){
    }
}

public class TestLambda {
    public static void main(String[] args) {
        //对void test方法进行了实现,且只能有一个抽象方法,并对其进行修饰
        LambdaInterface lam = ()->{
            System.out.println("aaaaaa");
        };
    }
}

有参:

public interface LambdaInterface {
    public abstract void test(int a ,int b);
}

public class TestLambda {
    public static void main(String[] args) {
        LambdaInterface lam = (a,b)->{
            System.out.println("aaaaaa"+a+b);
        };
    }
}

有返回值:

public interface LambdaInterface {
    public abstract int test(int a ,int b);
}

public class TestLambda {
    public static void main(String[] args) {
       LambdaInterface lam = (a,b)->{
            return a+b;
        };
    }
}

总结:

  • 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的应用:

//创建线程,用lambda实现
new Thread(
        ()->{
            System.out.println("线程要做得事情");
        }
).start();

//GUI组件添加事件监听
JButton jb = new JButton("按钮");
jb.addActionListener((e)->{

});

功能接口

Lambda 表达式只支持函数式接口 也就是只有一个抽象方法的接口.功能接口是 java 8 中的新增功能,它们只允许一个抽象方法。这些接口也称为单抽 象方法接口。Java 8 也引入了一个注释,即@FunctionalInterface,当你注释的接口违反了 Functional Interface 的契约时,它可以用于编译器级错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值