page contents

Java Lambda表达式详解教程

本文讲述了Java Lambda表达式详解教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-07-RPPSOUOv64ab6459318ca.png本文讲述了Java Lambda表达式详解教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

Lambda 表达式是 JDK8 的一个新特性,也被称为闭包,Lambda表达式允许把函数作为一个方法的参数,即行为参数化,函数作为参数传递进方法中。

Lambda表达式可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。

Lambda表达式的作用

Java 8 引入的 Lambda表达式的主要作用就是简化代码,写出更优雅的代码。

怎么一个简化优雅呢,举一Lambda语法创建线程和匿名内部类创建线程的例子,就非常清楚了。

1.匿名类创建线程

// JDK7匿名内部类写法

new Thread(new Runnable() {//接口名

        @Override

        public void run() {//方法名

            System.out.println("mikechen");


        }


    });


2.Lambda表达式创建线程

// JDK8 Lambda来创建线程


new Thread(() -> System.out.println("mikechen"));

上述代码跟匿名内部类的作用是一样的,但比匿名内部类更进一步,这里连接口名和函数名都一同省掉了,Lambda表达式可以取代匿名内部类,写出更优雅的代码。

Lambda表达式的语法

lambda 表达式的语法格式如下:

attachments-2023-07-sRSXlqb464ab63d7c6e4d.png():左侧部分指定了Lambda表达式需要的所有参数。

->:Lambda表达式的操作符或者箭头操作符。

{}:右侧部分指定了Lambda体,即方法需要实现的内容。

attachments-2023-07-KvvjoS5i64ab6413185e9.png

1.无参数

Lambda体只有一条语句:


示例:


() -> System.out.println("mikechen");


请注意,括号中没有内容。那就是表示lambda不带任何参数。


2.一个参数

示例:


Consumer<String> con = (x) -> System.out.println(x);


当lambda表达式是单个参数时,也可以省略括号,如下所示:


Consumer<String> con = x -> System.out.println(x);


3.多个参数

如果Java lambda表达式匹配的方法有多个参数,则需要在括号内列出这些参数,代码如下:


BinaryOperator<Integer> bo = (a, b) -> {


System.out.println("函数式接口");


return a + b;


};


注意:仅当方法是单个参数时,才可以省略括号。


4.指定参数类型

如果编译器无法从lambda匹配的函数式接口抽象方法推断参数类型,则有时可能需要为lambda表达式指定参数类型。


(Car car) -> System.out.println("The car is: " + car.getName());


如你所见,car参数的类型(Car)写在参数名称的前面,就像在其他方法中声明参数或对接口进行匿名实现时一样。


5.只有一条语句时

当Lambda体只有一条语句时,return和大括号可以省略,示例:


BinaryOperator<Integer> bo = (a, b) -> a + b;


6.参数类型不写

Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器能够通过上下文推断出数据类型,这就是“类型推断”,示例:


BinaryOperator<Integer> bo = (Integer a, Integer b) -> {


return a + b;


};


等同于


BinaryOperator<Integer> bo = (a, b) -> {


return a + b;


};


上述 Lambda 表达式中的参数类型都是由编译器推断得出,Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。


Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的,这就是所谓的“类型推断”。


7.Lambda表达式返回值

你可以从Java lambda表达式返回值,就像从方法中返回值一样。你只需向lambda表达式主体添加一个return,如下所示:


(param) -> {


    System.out.println("param: " + param);


    return "return value";


  }


 


函数式接口

Lambda表达式需要函数式接口的支持,所以,我们有必要来说说什么是函数式接口。


@Documented


@Retention(RetentionPolicy.RUNTIME)


@Target(ElementType.TYPE)


public @interface FunctionalInterface {}


一种用于表示一个接口是Java语言规范定义的函数式接口的注解类型。


对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方。


public interface MyFunctionInterface<T> {


public T getValue(T t);


}


为了确保函数式接口的正确性,我们可以给这个接口添加@FunctionalInterface注解,这样当其中有超过一个抽象方法时就会报错。


Unexpected @FunctionalInterface annotation


@FunctionalInterface ^ WorkerInterface is not a functional interface multiple


 non-overriding abstract methods found in interface WorkerInterface 1 error


Java 8中每一个Lambda表达式必须有一个函数式接口与之对应,也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。


 


Lambda表达式的举例

学习 Lambda 表达式的最好方式是学习例子,下面我们看几个比较常用的例子。


1.lambda创建线程

使用() -> {} 替代匿名类:


//JDK 8之前


new Thread(new Runnable() {


@Override


public void run() {


System.out.println("使用匿名内部类,开线程");


}


}).start();


 


//JDK 8 使用lambda表达式


new Thread(() -> System.out.println("使用lambda表达式,开线程")).start();


2.lambda事件处理

使用lambda表达式如下所示写出更好的事件侦听器的代码:


// Java 8之前:


button.addActionListener(new ActionListener() {


@Override


public void actionPerformed(ActionEvent e) {


System.out.println("Button被点击了使用老的方式!");


}


});


 


// Java 8方式:


button.addActionListener( (e) -> {


System.out.println("Button被点击了使用Lambda表达式!");


});


3.lambda遍历List集合

集合的遍历,采用lambda表达式会更简洁:


// Java 8之前:


List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");


for (String feature : features) {


System.out.println(feature);


}


 


// Java 8之后:


List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");


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


 


// 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示,


features.forEach(System.out::println);


方法引用是使用两个冒号::这个操作符号。


4.元素排序

之前我们若要为集合内的元素排序,就必须调用 sort 方法,传入比较器重写 compare。


方法的比较器对象,现在我们还可以使用 lambda 表达式来简化代码。


public static void main(String[] args) {


    List<String> list = new ArrayList<>();


    list.add("a");


    list.add("d");


    list.add("b");


    list.add("c");


    list.sort((o1,o2)->o1.compareTo(o2));


    list.forEach(System.out::println);


}


5.lambda Map

// 不使用lambda表达式为每个订单加上12%的税


List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);


for (Integer cost : costBeforeTax) {


double price = cost + .12*cost;

System.out.println(price);

}

// 使用lambda表达式

List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);

costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println);

6.lambda过滤String

// 创建一个字符串列表,每个字符串长度大于2

List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());

System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);

7.lambda对集合应用函数

// 将字符串换成大写并用逗号链接起来

List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada");

String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));

System.out.println(G7Countries);

8.lambda计算最大值、最小值、平均值

//获取数字的个数、最小值、最大值、总和以及平均值

List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);

IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();

System.out.println("Highest prime number in List : " + stats.getMax());

System.out.println("Lowest prime number in List : " + stats.getMin());

System.out.println("Sum of all prime numbers : " + stats.getSum());

System.out.println("Average of all prime numbers : " + stats.getAverage());

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Java编程语言,推荐大家关注一个微信公众号:Java圈子。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Java入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2023-03-2AoKIjPQ64014b4ad30a3.jpg

  • 发表于 2023-07-10 09:53
  • 阅读 ( 174 )
  • 分类:Java开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章