Java8新特性——Lambda表达式之四大核心函数式接口 & 方法/构造器/数组引用

简介: Java8新特性——Lambda表达式之四大核心函数式接口 & 方法/构造器/数组引用

文章目录:


1.四大核心函数式接口

1.1 Consumer : 消费型接口

1.2 Supplier : 供给型接口

1.3 Function : 函数型接口

1.4 Predicate : 断言型接口

2.方法引用

2.1 对象 :: 实例方法

2.2 :: 静态方法

2.3 :: 实例方法

3.构造器引用

4.数组引用

1.四大核心函数式接口


上一篇文章中说到了Lambda表达式中的基本语法,以及我们如何自定义函数式接口。但是在写代码的过程中,大家可能会发现一个问题:当我们有一个新的需求时,可以去自定义一个函数式接口,然后再创建一个它的实现类定义一些相关的业务逻辑行为。那么如果说我们有很多需求、这些需求可能还会不断地变化,那么我们岂不是每次都要去创建新的实现类、同时再去修改之前创建好的实现类中的业务代码?这可太麻烦了吧。。。

所以呢,Java8就为我们提供了四大核心函数式接口,使用起来非常的方便。


1.1 Consumer<T> : 消费型接口

package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
 * 
 */
public class MyTest3 {
    //Consumer<T> : 消费型接口
    @Test
    public void test1() {
        happy(6666.66,(m) -> System.out.println("本地双11共消费 " + m + " 元!!!"));
    }
    public void happy(double money, Consumer<Double> consumer) {
        consumer.accept(money);
    }
}


1.2 Supplier<T> : 供给型接口

package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
 *
 */
public class MyTest3 {
    //Supplier<T> : 供给型接口
    @Test
    public void test2() {
        List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
        for (Integer num : numList) {
            System.out.println(num);
        }
    }
    public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            Integer n = supplier.get();
            list.add(n);
        }
        return list;
    }
}


1.3 Function<T, R> : 函数型接口

package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
 * 
 */
public class MyTest3 {
    //Function<T, R> : 函数型接口
    @Test
    public void test3() {
        String trimStr = strHandler("\t\t\t  张起灵-小哥   ", (str) -> str.trim());
        System.out.println(trimStr);
        String newStr = strHandler("我喜欢看盗墓笔记呀!!!",(str) -> str.substring(4,8));
        System.out.println(newStr);
    }
    public String strHandler(String str, Function<String,String> function) {
        return function.apply(str);
    }
}


1.4 Predicate<T> : 断言型接口

package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
 *
 */
public class MyTest3 {
    //Predicate<T> : 断言型接口
    @Test
    public void test4() {
        List<String> list = Arrays.asList("Hello","张起灵-小哥","HashMap","jdk8","List","Set");
        List<String> stringList = filterStr(list, (s) -> s.length() > 5);
        for (String string : stringList) {
            System.out.println(string);
        }
    }
    public List<String> filterStr(List<String> strings, Predicate<String> predicate) {
        List<String> strList = new ArrayList<>();
        for (String str : strings) {
            if (predicate.test(str)) {
                strList.add(str);
            }
        }
        return strList;
    }
}


除此之外,还有一些其他的函数式接口,它们有一部分是上面提到的四大核心函数式接口的子接口。


2.方法引用


当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!     方法引用:使用操作符 “ :: ” 将方法名和对象或类的名字分隔开来。


如下三种主要使用情况

·       对象 :: 实例方法

·       :: 静态方法

·       :: 实例方法


可以将方法引用理解为 Lambda 表达式的另外一种表现形式,方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!


2.1 对象 :: 实例方法

    @Test
    public void test1() {
        Consumer<String> con1 = (str) -> System.out.println(str);
        con1.accept("Hello World!!!");
        PrintStream ps = System.out;
        Consumer<String> con2 = ps::println;
        con2.accept("Hello Java8!!!");
        Consumer<String> con3 = System.out::println;
        con3.accept("Hello Lambda!!!");
    }

    @Test
    public void test2() {
        Employee emp = new Employee();
        emp.setName("张起灵");
        emp.setAge(18);
        Supplier<? extends Object> sup1 = () -> emp.getName();
        String str = (String) sup1.get();
        System.out.println(str);
        Supplier<Integer> sup2 = emp::getAge;
        Integer age = sup2.get();
        System.out.println(age);
    }
package com.szh.java8;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 *
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    private Double salary;
    public Employee(Integer id) {
        this.id = id;
    }
    public Employee(Integer id,String name) {
        this.id = id;
        this.name = name;
    }
}


2.2 :: 静态方法

    @Test
    public void test3() {
        Comparator<Integer> com1 = (x,y) -> Integer.compare(x,y);
        System.out.println(com1.compare(10, 20));
        Comparator<Integer> com2 = Integer::compare;
        System.out.println(com2.compare(300, 110));
    }


2.3 :: 实例方法

Lambda 的参数列表的第一个参数是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式:ClassName::MethodName

    @Test
    public void test4() {
        BiPredicate<String,String> bp1 = (str1,str2) -> str1.equals(str2);
        System.out.println(bp1.test("Hello", "hello"));
        BiPredicate<String,String> bp2 = String::equals;
        System.out.println(bp2.test("Java", "Java"));
    }

3.构造器引用


格式 ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。构造器的参数列表,需要与函数式接口中参数列表保持一致!

代码中Employee类参考上面的案例。

    @Test
    public void test5() {
        //无参构造器
        Supplier<Employee> sup1 = () -> new Employee();
        System.out.println(sup1.get());
        //无参构造器
        Supplier<Employee> sup2 = Employee::new;
        System.out.println(sup2.get());
        //一个参数构造器
        Function<Integer,Employee> function = Employee::new;
        Employee employee = function.apply(1001);
        System.out.println(employee);
        //两个参数构造器
        BiFunction<Integer,String,Employee> biFunction = Employee::new;
        Employee emp = biFunction.apply(1001, "张起灵");
        System.out.println(emp);
    }


4.数组引用


格式:类型[] :: new

    @Test
    public void test6() {
        Function<Integer,String[]> fun = (x) -> new String[x];
        String[] strings = fun.apply(10);
        System.out.println(strings.length);
        Function<Integer,String[]> fun2 = String[]::new;
        String[] strArray = fun2.apply(50);
        System.out.println(strArray.length);
    }

相关文章
|
20天前
|
人工智能 前端开发 Java
Java 面试资料中相关代码使用方法与组件封装方法解析
这是一份详尽的Java面试资料代码指南,涵盖使用方法与组件封装技巧。内容包括环境准备(JDK 8+、Maven/Gradle)、核心类示例(问题管理、学习进度跟踪)、Web应用部署(Spring Boot、前端框架)、单元测试及API封装。通过问题库管理、数据访问组件、学习进度服务和REST接口等模块化设计,帮助开发者高效组织与复用功能,同时支持扩展如用户认证、AI推荐等功能。适用于Java核心技术学习与面试备考,提升编程与设计能力。资源链接:[点此下载](https://pan.quark.cn/s/14fcf913bae6)。
52 6
Java 面试资料中相关代码使用方法与组件封装方法解析
|
21天前
|
JavaScript 前端开发 Java
Java 编程进阶实操中工具集整合组件封装方法与使用指南详解
本文详细介绍Hutool工具集和图书管理系统相关组件的封装方法及使用示例。通过通用工具类封装(如日期格式化、字符串处理、加密等)、数据库操作封装(结合Hutool DbUtil与MyBatis)、前端Vue组件封装(图书列表与借阅表单)以及后端服务层封装(业务逻辑实现与REST API设计),帮助开发者提升代码复用性与可维护性。同时,提供最佳实践建议,如单一职责原则、高内聚低耦合、参数配置化等,助力高效开发。适用于Java编程进阶学习与实际项目应用。
92 10
|
1月前
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
171 0
|
6月前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
7月前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
7月前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
82 0
|
9月前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的探索
【9月更文挑战第24天】本文将深入浅出地介绍Java 8中的重要新特性——Lambda表达式和Stream API,通过实例解析其语法、用法及背后的设计哲学。我们将一探究竟,看看这些新特性如何让Java代码变得更加简洁、易读且富有表现力,同时提升程序的性能和开发效率。
|
10月前
|
Java API
Java 8新特性:Lambda表达式与Stream API的深度解析
【7月更文挑战第61天】本文将深入探讨Java 8中的两个重要特性:Lambda表达式和Stream API。我们将首先介绍Lambda表达式的基本概念和语法,然后详细解析Stream API的使用和优势。最后,我们将通过实例代码演示如何结合使用Lambda表达式和Stream API,以提高Java编程的效率和可读性。
|
10月前
|
存储 算法 Oracle
19 Java8概述(Java8概述+lambda表达式+函数式接口+方法引用+Stream+新时间API)
19 Java8概述(Java8概述+lambda表达式+函数式接口+方法引用+Stream+新时间API)
108 8
|
10月前
|
Java API
Java8 Lambda 设计和实现问题之在Java 8的Stream API中,parallel=false时collect方法是如何实现的
Java8 Lambda 设计和实现问题之在Java 8的Stream API中,parallel=false时collect方法是如何实现的