Java中四个重要的函数式接口:Function、Predicate、Consumer和Supplier。这些接口是函数式编程的基础,Function用于转换操作,Predicate用于进行条件判断,Consumer用于消费输入而不产生输出,而Supplier则用于提供值但不接受参数。本文重点介绍Supplier接口。
供应商接口(Supplier Interface)是 Java 8 引入的 java.util.function 包的一部分,用于在 Java 中实现函数式编程。
一、 函数接口Supplier简介
Supplier 是一个泛型的函数接口,无参数(该函数不接收任何参数),返回值类型为泛型 T,是返回结果的数据类型。Supplier 的使用比较简单,使用场景也比较单一。
Supplier 函数接口在 Java 8 中定义,其源代码如下:
package java.util.function;@FunctionalInterfacepublic interface Supplier<T> {T get();}
Supplier 由于没有参数输入,所以多用于对象创建,类似于一个对象创建工厂。可以使用 Lambda 方式创建任意对象,也可以使用对象构造器的方法引用创建对象。
//定义一个日期时间的供应者创建工厂,Lambda表达式创建供应商实例Supplier < LocalDateTime > supplier = () -> LocalDateTime.now();System.out.println(supplier.get());//定义一个日期时间的供应者创建工厂,方法调用创建供应商实例Supplier<LocalDateTime> supplierDate = LocalDateTime::now;System.out.println(supplierDate.get());
二、函数接口Supplier应用示例:
- 应用示例(一)
先定义一个实体类:
package function;
public class Product {private int id;private String name;private float price;public Product(int id, String name, float price) {super();this.id = id;this.name = name;this.price = price;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;}@Overridepublic String toString() {return "产品 [id=" + id + ", 品名=" + name + ", 单价=" + price + "]";}
}
测试主控类的代码:
package function;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
public class SupplierDemo {private static Supplier<List< Product >> productSupplier() {Supplier < List < Product >> supplierList = () -> {List< Product > productList = new ArrayList<>();productList.add(new Product(1, "娃哈哈纯净水", 2));productList.add(new Product(2, "比亚迪汽车", 160000f));productList.add(new Product(3, "白象方便面", 3f));productList.add(new Product(4, "南方黑芝麻糊", 3f));productList.add(new Product(5, "华为手机", 6000f));return productList;};return supplierList;}public static void main(String[] args) throws Exception {/***匿名内部类创建供应商实例***/Supplier<String> dateTimeSupplier = new Supplier<String>() {@Overridepublic String get() {LocalDateTime localDateTime = LocalDateTime.now();DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");return localDateTime.format(pattern);}};System.out.println("日期时间Supplier测试,开始:");System.out.println("第一次时间:" + dateTimeSupplier.get());Thread.sleep(1000L);System.out.println("第二次时间:" + dateTimeSupplier.get());//Lambda表达式创建随机整型数供应商实例Supplier<Integer> supplierRdm = () -> new Random().nextInt(10);System.out.println(supplierRdm.get());System.out.println(supplierRdm.get());//供应商工厂演示Supplier < List < Product >> supplier2 = SupplierDemo.productSupplier();List< Product > list = supplier2.get();list.forEach(System.out::println);}
}
测试结果图:
- 应用示例(二)
supplier在工厂模式中的应用:
先定义一个实体类
package function;
public class Dog {private final String name;private Integer age=2;public Dog(String name) {this.name = name;}public Dog(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "宠物狗 {" + "昵称='" + name + "', 年龄=" + age + '}';}
}
测试主控程序类:
package function;
import java.util.function.Supplier;
public class SupplierTest {/***定义一个供应者的工厂类***/public static Dog dogFactory(Supplier<? extends Dog> supplier) {Dog dog = supplier.get();return dog;}public static void main(String[] args) {Dog dog1 = dogFactory(() -> new Dog("哈士奇"));Dog dog2 = dogFactory(() -> new Dog("牧羊犬",3));Dog dog3 = dogFactory(() -> new Dog("泰迪",1));System.out.println(dog1);System.out.println(dog2);System.out.println(dog3);}
}
例程测试效果图:
三、 Supplier 扩展类
在 Java 8 的类库中,为了方便 Supplier 的使用,提供了基本数据类型的专用 Supplier,例如 BooleanSupplier, DoubleSupplier, IntSupplier, LongSupplier。
下面是一个LongSupplier使用示例:
package function;
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.util.function.LongSupplier;public class LongSupplierDemo {public static void main(String[] args) throws Exception {LongSupplier supplier = new LongSupplier() {@Overridepublic long getAsLong() {LocalDateTime dateTime = LocalDateTime.now();return dateTime.getLong(ChronoField.SECOND_OF_DAY);}};for (int i = 0; i < 3; i++) {System.out.println("第"+(i+1)+"次:" + supplier.getAsLong());Thread.sleep(1000L);}}}
测试结果(这个结果是变化的):
参考文献:
- Java 8 Supplier 函数接口
- Java 8 Supplier函数式接口介绍及代码样例