Java学习——lambda表达式

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

一 、Lambda表达式前瞻知识

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

为什么要引入Lambda表达式?
Lambda表达式能够让程序员的编程更加高效

lambda表达式和方法引用使用前提:函数式接口
1.@FunctionalInterface 语法格式严格要求当前接口有且只能有一个尚未完成的缺省属性为 public abstract 修饰方法
2.函数式接口一般用于方法的增强,直接作为方法的参数,实现函数式编程。
只有函数式接口的变量或者是函数式接口,才能够赋值为Lambda表达式。这个接口中,可以有默认方法,或者是静态方法。

二、Lambda表达式

1.Lambda表达式的基本语法

([Lambda参数列表,即形参列表]) -> {Lambda体,即方法体}
1.Lambda 表达式关注的是接口中方法的返回值和参数,方法名不重要
2.使用 "->"将参数和实现逻辑分离;( ) 中的部分是需要传入Lambda体中的参数;{ } 中部分,接收来自 ( ) 中的参数,完成一定的功能。
3.只有函数式接口的变量或者是函数式接口,才能够赋值为Lambda表达式。这个接口中,可以有默认方法,或者是静态方法。

2.四种lambda表达式

2.1无参数无返回值
//接口设计
@FunctionalInterface
interface A {
	void 方法名真的没有用();
}
//方法设计
public static void testLambda(A a) {
    a.方法名真的没有用();
}
//代码实现
public static void main(String[] args) {
	//1.匿名内部类方法
	//接口无法实例化,这里实例化的是 A 接口的实现类对象(该方法在jdk1.8以后被lambda表达式完虐)
    testLambda(new A() {
    	//缺省属性为abstract,需要重写
        @Override
        public void 方法名真的没有用() {
            System.out.println("无参数返回值 匿名内部类对象方法实现");
        }
    });

    /*
    2. Lambda 表达式实现
    【分析】
        void 方法名真的没有用();
        接口方法【返回值类型】 void,无返回值
        接口方法【参数】 无参数
     */
    testLambda(() -> {
        System.out.println("Lambda 表达式初体验");
    });

    //Lambda 表达式有且只有一行代码,可以省略大括号
    testLambda(() -> System.out.println("Lambda 表达式初体验"));
2.2无参数有返回值

生产者接口
Supplier < T> T get() 无参有返回值的抽象方法;

//接口设计
@FunctionalInterface
interface Supplier<T> {
    /**
    * 无参数有返回值方法,泛型约束的是接口对应的返回值数据类型,要求按照泛型约束返回对应的数据内容
    *
    * @return 返回一个数据,符合泛型约束
    */
	T get();
}
/*
 * 当前方法要求返回一个字符串数据内容
 */
public static String testLambda(Supplier<String> s) {
    return s.get();
}
public static void main(String[] args) {
     /*
    【分析】
        T get(); ==> 泛型约束为 String ==> String get();
        接口方法【返回值类型】 String
        接口方法【参数】 无参数
     Lambda 格式:() -> {必须返回一个 String 类型}
     */
    String s1 = testLambda(() -> {
        return "这里也是一个字符串";
    });
    System.out.println(s1);

    /*
    Lambda 优化,只要 -> 之后是一个 字符串数据内容就可以满足当前 Lambda 所需
    可以省略 return ,前提是当前 Lambda 有且只有一行代码
     */
    String s2 = testLambda(() -> "这里也是一个字符串");
    System.out.println(s2);

    /*
    Lambda 内部使用使用方法局部变量
     */
    String str = "name=王小明&age=23&country=中国";
    String s3 = testLambda(() -> {
        // str 是当前 main 方法局部变量,Lambda 内部可以直接使用
        String[] split = str.split("&");
        return split[0];
    });
    System.out.println(s3);//返回王小明
}
2.3有参数无返回值

消费型接口
Consumer< T> void accept(T t)有参数,无返回值的抽象方法;

@FunctionalInterface
interface Consumer<T> {
    /**
    * 消费者接口,数据最终处理接口,数据处理终止方法接口,对应的方法要求方法有参数无返回值
    *
    * @param t 泛型数据数据类型 T ,支持任意类型,在接口约束之后,要求符合数据类型一致化要求
    */
	void accept(T t);
}
/**
 * 有参数无返回 Lambda 测试方法,方法参数是 String 类型和针对于 String 类型
 * 进行数据处理的 Consumer 接口,Consumer 接口可以传入实现类对象和 Lambda 表达式
 *
 * @param str    目标处理的 String 字符串数据
 * @param handle 已经约束为处理 String 类型数据的 Consumer 接口处理器
 */
public static void testLambda(String str, Consumer<String> handle) {
    handle.accept(str);
}
public static void main(String[] args) {
    /*
    1、匿名内部类 Low
     */
    testLambda("孟州市炒面第一名", new Consumer<String>() {
        @Override
        public void accept(String t) {
            System.out.println(t);
        }
    });

    /*
    2. Lambda 表达式
    【分析】
        void accept(T t); ==> 泛型约束为 String ==> void accept(String t);
        接口方法【返回值】 void
        接口方法【参数】 1 个参数,String 类型
     Lambda 格式
        Lambda 小括号中的临时变量名称,没有数据类型体现,需要【联想】目标方法数据类型
        只按照参数的个数定义临时小变量
        (s) -> {大括号中无需返回值类型}
            Lambda 表达式临时变量 s 对应的数据类型为 String 类型 【联想可得】
     */
    testLambda("lambda表达式需要联想!!!", (s) -> {
        System.out.println(Arrays.toString(s.toCharArray()));
    });

    /*
    Lambda 优化
        1. 代码块有且只有一行,可以省略大括号
        2. 小括号中有且只有一个 参数,可以省略小括号

    【注意】
        Lambda 承担的角色是一个针对于 String 字符串的处理器
     */
    testLambda("lambda表达式需要联想!!!", s -> System.out.println(Arrays.toString(s.toCharArray())));
}
2.4有参数有返回值
  • 比较器接口
    Comparator< T> int compare(T o1, T o2)有参,返回值类型为int
  • 断定型接口(过滤器接口)
    Predicate< T> boolean test(T t)有参,但是返回值类型是固定的boolean
  • 函数型接口(类型转换器接口)
    Function< T,R> R apply(T t)有参,有返回值的抽象方法

1.比较器接口

// 比较器接口
@FunctionalInterface
interface Comparator<T> {
    /**
     * 比较器接口要求的方法,参数是泛型参数,用户指定类型
     *
     * @param o1 用户在使用接口时约束的泛型对应具体数据类型参数
     * @param o2 用户在使用接口时约束的泛型对应具体数据类型参数
     * @return 返回值为 int 类型,0 表示两个元素一致。
     */
    int compare(T o1, T o2);
}

/**
 * @author Anonymous 2023/3/3 11:30
 */
public class Demo1 {
    public static void main(String[] args) {
        Person[] array = new Person[5];

        for (int i = 0; i < array.length; i++) {
            int age = (int) (Math.random() * 50);
            array[i] = new Person(i + 1, "张三", age, false);
        }

        /*
        Lambda 分享
        方法
            int compare(T o1, T o2); ==> 泛型约束为 Person ==> int compare(Person o1, Person o2);
        方法返回值 int 类型
        方法参数
            1. 2个参数
            2. 参数数据类型都是 Person 类型
         Lambda 格式
            (o1, o2) -> {所需返回值为 int 类型}
         */
        sortPersonArrayUsingComparator(array, (o1, o2) -> o1.getId() - o2.getId());

        // Arrays.sort(array, (o1, o2) -> o1.getAge() - o2.getAge());

        for (Person person : array) {
            System.out.println(person);
        }
    }

    /**
     * 排序操作,排序数组为 Person 类型,排序规则使用自定义 Comparator 接口实现,接口泛型约束 Person
     * 类型
     *
     * @param array     Person 类型数组
     * @param condition 针对于 Person 类型数组的 Comparator 比较器接口实现
     */
    public static void sortPersonArrayUsingComparator(Person[] array, Comparator<Person> condition) {
        for (int i = 0; i < array.length - 1; i++) {
            int index = i;

            for (int j = i + 1; j < array.length; j++) {
                /*
                condition 是自定义 Comparator 排序接口方法,目前泛型约束为 Person 类型
                int compare(T o1, T o2); ==> int compare(Person o1, Person o2);
                当前数组存储的数据类型就是 Person 对象,可以作为 compare 方法参数,同时
                利用 compare 方法返回 int 类型数据,作为排序算法规则的限制。
                 */
                if (condition.compare(array[index], array[j]) > 0) {
                    index = j;
                }
            }

            if (index != i) {
                Person temp = array[index];
                array[index] = array[i];
                array[i] = temp;
            }
        }
    }
}

问题解答:为什么约束类型为Person
java lambda表达式,笔记,java,学习,jvm

2.过滤器接口

// 过滤器接口,判断器接口,条件接口
@FunctionalInterface
interface Predicate<T> {
    /**
     * 过滤器接口约束的方法,方法参数是用户使用时约束泛型对应具体数据参数
     * 返回值类型是 boolean 类型,用于条件判断,数据过来
     *
     * @param t 用户约束泛型对应的具体数据类型参数
     * @return boolean 数据,判断结果反馈
     */
    boolean test(T t);
}

public class Demo2 {
    public static void main(String[] args) {
        Person[] array = new Person[5];

        for (int i = 0; i < array.length; i++) {
            int age = (int) (Math.random() * 50);
            array[i] = new Person(i + 1, "张三", age, false);
        }

        /*
        Lambda 分析
            boolean test(T t); ==> 泛型约束为 Person 类型 ==> boolean test(Person t);
        方法返回值是 boolean
        方法参数
            1. 1 个
            2. Person 类型
         Lambda 格式
            p -> {要求必须返回一个 boolean}
         */
        Person[] temp = filterPersonArrayUsingPredicate(array, p -> p.getAge() > 10);

        for (Person person : temp) {
            System.out.println(person);
        }

    }

    /**
     * 过滤限定操作,利用 Predicate 过滤器接口限定数组内容
     *
     * @param array  Person 类型数组
     * @param filter Predicate 过滤器参数
     * @return 过滤限定之后的新数组
     */
    public static Person[] filterPersonArrayUsingPredicate(Person[] array, Predicate<Person> filter) {
        Person[] temp = new Person[array.length];

        int count = 0;
        for (int i = 0; i < array.length; i++) {
            /*
             Predicate 接口提供的方法是  boolean test(T t);
             目前泛型约束之后是 boolean test(Person t);
             判断当前 Person 对象是否满足要求,如果满足,存储到 temp 数组中。
             */
            if (filter.test(array[i])) {
                temp[count++] = array[i];
            }
        }

        return temp;
    }
}

3.类型转换器接口

// 类型转换器接口
@FunctionalInterface
interface Function<T, R> {
	R apply(T t);	
}

public class Demo3 {
    public static void main(String[] args) {
        String str = "开封有个包青天";

        /*
        Lambda 分析
            R apply(T t); ==> 泛型约束 T => String R => Integer
            Integer apply(String t);

        Lambda 格式
            返回值类型 Integer
            方法参数
                1. 1个
                2. String
            s -> {必须返回 int 类型数据}
         */
        int i = testLambda(str, s -> s.length());
        System.out.println(i);
    }

    public static int testLambda(String str, Function<String, Integer> fun) {
        return fun.apply(str);
    }
}

三、方法引用(拓展):

当Lambda表达式满足某种条件的时候,使用方法引用,可以再次简化代码

1.构造引用

当Lambda表达式是通过new一个对象来完成的,那么可以使用构造引用。

import java.util.function.Supplier;
public class TestLambda {
    public static void main(String[] args) {
//        Supplier<Student> s = () -> new Student();
 
        Supplier<Student> s = Student::new;
    }//实际过程:将new Student()赋值给了Supplier这个函数式接口中的那个抽象方法
}

2.类名::实例方法

Lambda表达式的的Lambda体也是通过一个对象的方法完成,但是调用方法的对象是Lambda表达式的参数列表中的一个,剩下的参数正好是给这个方法的实参。文章来源地址https://www.toymoban.com/news/detail-765139.html

import java.util.TreeSet;
public class TestLambda {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>((s1,s2) -> s1.compareTo(s2));
}

3.对象::实例方法

*/ //类名::实例方法
        TreeSet<String> set = new TreeSet<>(String::compareTo);
        set.add("Hello");
        set.add("isea_you");
       // set.forEach(t -> System.out.println(t));//Hello \n isea_you
        set.forEach(System.out::println);
        //(1)对象::实例方法,Lambda表达式的(形参列表)与实例方法的(实参列表)类型,个数是对应
    }
}

4.类名::静态方法

package com.isea.java;
import java.util.stream.Stream;
public class TestLambda {
    public static void main(String[] args) {
//        Stream<Double> stream = Stream.generate(() -> Math.random());
//        类名::静态方法, Lambda表达式的(形参列表)与实例方法的(实参列表)类型,个数是对应
        Stream<Double> stream = Stream.generate(Math::random);
        stream.forEach(System.out::println);
    }
}

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

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

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

相关文章

  • 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表达式详解

    我们知道,在Java中,接口是不能实例化的,但是接口对象可以指向它的实现类对象。如果接口连实现对象都没有呢?那还可以使用匿名类的方式,如下: 复制 但是,使用匿名内部的方式,代码量其实并不是非常简洁,而为了使代码更加的简洁,Java引进了 Lambda 表达式的写法,

    2024年02月03日
    浏览(50)
  • 【Java基础】Java Lambda表达式详解

    Lambda 表达式,即函数式编程是 JDK8 的一个新特性,也被称为闭包,Lambda表达式允许把函数作为一个方法的参数,即行为参数化,函数作为参数传递进方法中。 Lambda表达式可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大

    2024年02月04日
    浏览(55)
  • 【JAVA】包装类、正则表达式、Arrays类、Lambda表达式

    包装类是8种基本数据类型对应的引用类型 作用:后期的集合和泛型不支持基本类型,只能使用包装类 基本数据类型和其对应的引用数据类型的变量可以互相赋值 基本数据类型 引用数据类型 byte Byte short Short int Integer long Long char Character float Float double Double boolean Boolean 包装类

    2024年02月13日
    浏览(58)
  • 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)
  • Java 8 Lambda表达式详解

    在Java 8中,引入了一种全新的函数编程概念,即Lambda表达式。这是一个重要的进步,它让Java的功能得以大幅扩展,同时还让代码变得更加简洁明了。接下来,我将详细介绍Lambda表达式的相关知识,包括其基本语法、使用场景和特性。 Lambda表达式基本的语法可以分为三个部分

    2024年02月08日
    浏览(84)
  • 【Java系列】深入解析 Lambda表达式

      你只管努力,其他交给时间,时间会证明一切。 文章标记颜色说明: 黄色 :重要标题 红色 :用来标记结论 绿色 :用来标记一级论点 蓝色 :用来标记二级论点 希望这篇文章能让你不仅有一定的收获,而且可以愉快的学习,如果有什么建议,都可以留言和我交流 Java La

    2024年02月10日
    浏览(52)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包