【Java基础】Java Lambda表达式详解

这篇具有很好参考价值的文章主要介绍了【Java基础】Java Lambda表达式详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

总结就是:使用不可变值与函数,函数对不可变值进行处理,映射成另一个值。


一、什么是函数式接口

函数接口是只有一个抽象方法的接口,用作 Lambda 表达式的类型。使用@FunctionalInterface注解修饰的类,编译器会检测该类是否只有一个抽象方法或接口,否则,会报错。可以有多个默认方法,静态方法。

lambda 表达式是一小段代码,它接受参数并返回一个值。Lambda 表达式类似于方法,但它们不需要名称,并且可以直接在方法体中实现。

语法:最简单的 lambda 表达式包含一个参数和一个表达式:

  • 零参数:

() -> System.out.println("零参数 lambda");
  • 一个参数:

p -> System.out.println("一个参数:" + param);
  • 多个参数:

(p1 [,p2,p3,....pn]) -> System.out.println("多个参数:" + p1 + ", " + p2 + ... + pn);

上面的表达式有一定的限制。它们要么返回一个值要么执行一段方法,并且它们不能包含变量、赋值或语句,例如if or for 。为了进行更复杂的操作,可以使用带有花括号的代码块。如果 lambda 表达式需要返回一个值,那么代码块应该有一个return语句。


(parameter1, parameter2) -> { code block [return] }

1、方法引用

  • 类 :: 静态方法

Consumer<String> c = [ (s) -> System.out.println(s);  <=>  System.out::println; ]
  • 对象 :: 实例方法

List<String> list = Lists.newArrayList();
Consumer<String> c = [ (e) => list.add(e);  <=>  list::add; ]
  • 构造器 :: new

Supplier<List<String>> s = [ () -> new ArrayList<>(); <=> ArrayList::new; ]

2、@FunctionalInterface注解

有且只有一个抽象方法的接口被称为函数式接口,函数式接口适用于函数式编程的场景,Lambda就是Java中函数式编程的体现,可以使用Lambda表达式创建一个函数式接口的对象,一定要确保接口中有且只有一个抽象方法,这样Lambda才能顺利的进行推导。

与@Override 注解的作用类似,Java 8中专门为函数式接口引入了一个新的注解:@FunctionalInterface 。该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法(equal和hashcode方法不算),否则将会报错。但是这个注解不是必须的,只要符合函数式接口的定义,那么这个接口就是函数式接口。

3、 java8自带的常用函数式接口。

java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

4、简单的例子

package com.biyu.study.lambda;

import com.biyu.study.lambda.bean.Employee;

import java.math.BigDecimal;
import java.util.function.*;

public class Test {
    public static void main(String[] args) {
        Predicate<Integer> predicate = x -> x > 20;
        Employee employee = new Employee("Lily", "女", 18);
        System.out.println("Lily的大于18岁吗?:" + predicate.test(employee.getAge()));

        Consumer<String> consumer = System.out::println;
        consumer.accept("Hello World");

        Function<Employee, String> function = Employee::getName;
        String name = function.apply(employee);
        System.out.println(name);

        Supplier<Integer> supplier = () -> Integer.valueOf(BigDecimal.TEN.toString());
        System.out.println(supplier.get());

        UnaryOperator<Boolean> unaryOperator = uglily -> !uglily;
        Boolean apply2 = unaryOperator.apply(true);
        System.out.println(apply2);

        BinaryOperator<Integer> operator = (x, y) -> x * y;
        Integer integer = operator.apply(2, 3);
        System.out.println(integer);

        test(() -> "函数式接口");
    }

    /**
     * 自定义函数式接口使用
     *
     * @param worker
     */
    public static void test(Worker worker) {
        String work = worker.work();
        System.out.println(work);
    }

    public interface Worker {
        String work();
    }
}
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

以上演示了lambda接口的使用及自定义一个函数式接口并使用。

二、Lambda 流的常用方法

1、ForEach

集合的遍历 forEach 方法:

public static void testForEach(){
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
        }};

        list.forEach(s-> System.out.println(s));
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

2、Collect

将操作后的对象转化为新的对象:

public static void testCollect(){
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("2");
        }};

        //转换为新的list
        List newList = list.stream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());
        System.out.println(newList);
    }

3、Filter

Filter 为过滤的意思,只要满足 Filter 表达式的数据就可以留下来,不满足的数据被过滤掉。

public static void testFilter() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
        }};

        List<String> filtered = list.stream()
                // 过滤掉我们希望留下来的值
                // 表示我们希望字符串是 1 能留下来
                // 其他的过滤掉
                .filter(str -> "1".equals(str))
                .collect(Collectors.toList());
        System.out.println(filtered);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

4、Map

map 方法可以让我们进行一些流的转化,比如原来流中的元素是 A,通过 map 操作,可以使返回的流中的元素是 B。

public static void testMap() {
        List<String> list = new ArrayList<String>() {{
            add("A");
            add("B");
            add("C");
        }};
        //通过 map 方法list中元素转化成 小写
        List<String> strLowerList = list.stream()
                .map(str -> str.toLowerCase())
                .collect(Collectors.toList());
        System.out.println(strLowerList);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

5、MapToInt

mapToInt 方法的功能和 map 方法一样,只不过 mapToInt 返回的结果已经没有泛型,已经明确是 int 类型的流了。

public static void testMapToInt() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
        }};
        List<Integer> intList=list.stream()
                .mapToInt(s->Integer.valueOf(s))
                // 一定要有 mapToObj,因为 mapToInt 返回的是 IntStream,因为已经确定是 int 类型了,所以没有泛型的,
                // 而 Collectors.toList() 强制要求有泛型的流,所以需要使用 mapToObj方法返回有泛型的流
                .mapToObj(s->s)
                .collect(Collectors.toList());
        System.out.println(intList);
        Double sum = list.stream()
                .mapToDouble(s->Double.valueOf(s))
                // DoubleStream/IntStream 有许多 sum(求和)、min(求最小值)、max(求最大值)、average(求平均值)等方法
                .sum();
        System.out.println(sum);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

6、Distinct

distinct 方法有去重的功能:

public static void testDistinct() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("2");
            add("5");
            add("3");
        }};
        List<Integer> intList = list.stream()
                .map(s -> Integer.valueOf(s))
                .distinct()
                .collect(Collectors.toList());
        System.out.println(intList);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

7、Sorted

Sorted 方法提供了排序的功能,并且允许我们自定义排序。

public static void testSorted() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("-1");
            add("9");
            add("11");
            add("27");
            add("0");
        }};
        List<Integer> intList = list.stream()
                .map(s -> Integer.valueOf(s))
                // 等同于 .sorted(Comparator.naturalOrder()) 自然排序
                .sorted()
                .collect(Collectors.toList());
        System.out.println(intList);
        // 自定义排序器
        intList =list.stream()
                .map(s -> Integer.valueOf(s))
                // 反自然排序
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        System.out.println(intList);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

8、groupingBy

groupingBy 是能够根据字段进行分组,toMap 是把 List 的数据格式转化成 Map 的格式。

public static void testGroupBy() {
        List<String> list = new ArrayList<String>() {{
            add("iphone 4s");
            add("iphone 6");
            add("iphone 12");
            add("iphone 14");
            add("xiaomi");
            add("huawei");
            add("oppo");
        }};

        Map<String, List<String>> strList = list.stream().collect(Collectors.groupingBy(s -> {

            if (s.startsWith("iphone")){
                return "iphone";
            } else {
                return "other";
            }
        }));
        System.out.println(strList);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

9、FindFirst

findFirst 表示匹配到第一个满足条件的值就返回:

public static void testFindFirst() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("2");
        }};

        list.stream()
                .filter(s -> "2".equals(s))
                .findFirst()
                .get();

        // 防止空指针
        list.stream()
                .filter(s -> "2".equals(s))
                .findFirst()
                // orElse 表示如果 findFirst 返回 null 的话,就返回 orElse 里的内容
                .orElse("3");

        Optional<String> str = list.stream()
                .filter(s -> "2".equals(s))
                .findFirst();
        // isPresent 为 true 的话,表示 value != null
        if (str.isPresent()) {
            return;
        }
    }

10、Reduce

reduce 方法允许我们在循环里面叠加计算值:

public static void testReduce() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
        }};

        int sum = list.stream()
                .map(s -> Integer.valueOf(s))
                // s1 和 s2 表示循环中的前后两个数
                .reduce((s1, s2) -> s1 + s2)
                .orElse(0);
        System.out.println(sum);
        sum =list.stream()
                .map(s -> Integer.valueOf(s))
                // 第一个参数表示基数,会从 100 开始加
                .reduce(100, (s1, s2) -> s1 + s2);
        System.out.println(sum);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

11、Peek

peek 方法很简单,我们在 peek 方法里面做任意没有返回值的事情,比如打印日志:

public static void testPeek() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
        }};
        list.stream().map(s -> Integer.valueOf(s))
                .peek(s -> System.out.println(s))
                .collect(Collectors.toList());
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

12、Limit

limit 方法会限制输出值个数,入参是限制的个数大小:

public static void testLimit() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("2");
            add("3");
            add("4");
            add("5");
        }};
       List<Integer> integers= list.stream()
                .map(s -> Integer.valueOf(s))
                .limit(3L)
                .collect(Collectors.toList());
        System.out.println(integers);

    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

13、Max,Min

通过 max、min 方法,可以获取集合中最大、最小的对象。

public static void testMaxMin() {
        List<String> list = new ArrayList<String>() {{
            add("1");
            add("3");
            add("2");
            add("-12");
            add("99");
        }};

        String maxNum = list.stream().max(Comparator.comparing(s -> Integer.valueOf(s))).get();
        String minNum = list.stream().min(Comparator.comparing(s -> Integer.valueOf(s))).get();
        System.out.println(maxNum);
        System.out.println(minNum);
    }
java lambda,Java入门系列,零基础,Java,java,学习,开发语言,Powered by 金山文档

三、写在最后

本章节主要从实际使用讲述了常用的方法及流,文中例子主要是为了讲解较为简单,大家可以去使用java8重构自己现有的代码,自行领会lambda的奥妙使用。java8可以很清晰表达你要做什么,代码也很简洁。文章来源地址https://www.toymoban.com/news/detail-762703.html

到了这里,关于【Java基础】Java Lambda表达式详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java基础入门-12-【API(算法,lambda表达式,练习)】

    ​ 数据结构是数据存储的方式,算法是数据计算的方式。 ​ 也叫做顺序查找 ​ 说明:顺序查找适合于存储结构为数组或者链表。 基本思想 基本思想 :顺序查找也称为线形查找,属于无序查找算法。从数据结构线的一端开始,顺序扫描,依次将遍历到的结点与要查找的值

    2024年02月05日
    浏览(55)
  • 进阶JAVA篇- Lambda 表达式与 Lambda 表达式的省略规则

    目录         1.0 什么是 Lambda 表达式?         1.1 既然跟匿名内部类相关,先来回顾匿名内部类。          1.2 Lambda 表达式与匿名内部类之间的关系。         1.3 函数式接口         1.4 在具体代码中来操作一下         2.0 Lambda 表达式省略规则          Lambda 表达

    2024年02月08日
    浏览(55)
  • Lambda表达式(JAVA)

    注:如果没有学过 匿名内部类 和 接口 不推荐往下看。 (parameters) - expression 或 (parameters) -{ statements; } parameters:表示参数列表; -:可理解为“被用于”的意思; expression:表示一条语句; statements:表示多条语句。 Lambda可以理解为:Lambda就是匿名内部类的简化。 lambda表达式

    2024年02月08日
    浏览(54)
  • Java Lambda表达式

    1.1 函数式编程思想概括 在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作” 面向对象思想强调“必须通过对象的形式来做事情” 函数式思想则尽量忽略面

    2024年02月07日
    浏览(61)
  • Java Lambda 表达式

    💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Java Lambda 表达式是 Java 8 引入的一种函数式编程特性,它是一种轻量级的匿名函数,允许我们将函数作为方法的参数进行传递。Lambda 表达式可以理解为是一种简洁的方式来表示可传递的代码块,它可以替代传统的匿名内

    2024年02月08日
    浏览(55)
  • Java- Lambda表达式

    目录 一、Lambda简介 二、Lambda使用前提 三、Lambda语法 1.操作符 a.\\\"-\\\"  b.\\\"::\\\" 2.格式  a.无参数 b.有参数 四、Lambda演化过程 五、Lambda实现排序 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)

    2024年02月03日
    浏览(76)
  • Java中的lambda表达式

    目录 一、背景 二、lambada表达式的基本使用 三、变量捕获 四、lambda在集合中的使用(map和set) 五、优缺点 一、背景 (1)、lambda表达式的定义: (2)、lambda表达式的语法: (3)、函数式接口 二、lambada表达式的基本使用 (1)没有使用lambda表达式,简单调用函数式接口展

    2024年02月08日
    浏览(53)
  • Java学习——lambda表达式

    什么是Lambda表达式? 可以将Lambda表达式理解为一个匿名函数; Lambda表达式允许将一个函数作为另外一个函数的参数; 我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码作为实参),也可以理解为函数式编程, 将一个函数作为参数进行传递 。 为什么要引入Lambda表

    2024年02月04日
    浏览(66)
  • Java新特性:Lambda表达式

    Java新特性:Lambda表达式 Lambda 表达式(Lambda expression),也可称为闭包(Closure),是 Java(SE)8 中一个重要的新特性。Lambda 表达式允许我们通过表达式来代替功能接口。Lambda 表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表

    2024年02月13日
    浏览(56)
  • 浅谈 Java 中的 Lambda 表达式

    更好的阅读体验 huge{color{red}{更好的阅读体验}} 更好的阅读体验 Lambda 表达式是一种匿名函数,它可以作为参数传递给方法或存储在变量中。在 Java8 中,它和函数式接口一起,共同构建了函数式编程的框架。 函数式编程是一种编程范式,也是一种思想。 它将计算视为函数求

    2024年02月11日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包