Java``Supplier是一个功能接口,代表结果的提供者。

Supplier的功能方法是get()

一个Supplier可以通过lambda表达式、方法引用或默认构造函数来实例化。

SupplierJava 8中被引入,属于java.util.function包。

Supplier功能接口的源代码如下。

1
2
3
4
@FunctionalInterface
public interface Supplier<T> {
T get();
}

我们可以看到在上面的代码中,Supplierget()方法,可以返回通用类型的值。

get()方法不接受任何参数,只返回通用类型的值。

我们可以按以下方式实例化Supplier

1
Supplier<String> s = () -> "Hello World!";

Java还提供了返回特定类型值的Suppplier

BooleanSupplier返回Boolean数据类型,IntSupplier返回Integer数据类型,LongSupplier返回Long数据类型,DoubleSupplier返回Double数据类型值。

我们还可以根据我们的要求创建自定义的功能接口。

使用Lambda表达式实例化Supplier

我们将在这里使用lambda表达式来实例化Supplier

因为我们知道它的方法get()只返回值,不接受任何参数,所以我们的lambda表达式将有空的参数部分。

SupplierWithLambda.java

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.Random;
import java.util.function.Supplier;

public class SupplierWithLambda {
public static void main(String[] args) {
Supplier<String> s1 = () -> "Hello World!";
System.out.println(s1.get());

Random random = new Random();
Supplier<Integer> s2 = () -> random.nextInt(10);
System.out.println(s2.get());
}
}

输出

1
2
Hello World!
9

使用方法引用实例化Supplier

方法引用使用(::)符号来调用方法。假设我们有一个MyUtil类和一个静态方法getFavoriteBook(),那么我们可以用类名来调用它。

1
MyUtil::getFavoriteBook

如果我们有非静态方法,我们可以使用类的实例来调用这个方法。

假设myUtilMyUtil类的实例,getAge()是一个非静态方法,那么我们使用实例来调用它,如下所示。

1
myUtil::getAge

我们知道,Supplier功能接口的get()方法没有参数,所以我们的getFavoriteBook()getAge()方法不应该接受任何参数。

找到这个例子。

SupplierWithMethodReference.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Random;
import java.util.function.Supplier;

public class SupplierWithMethodReference {
public static void main(String[] args) {
Supplier<String> s1 = MyUtil::getFavoriteBook;
System.out.println(s1.get());

MyUtil myUtil = new MyUtil();
Supplier<Integer> s2 = myUtil::getAge;
System.out.println(s2.get());

Random random = new Random();
Supplier<Integer> s3 = random::nextInt;
System.out.println(s3.get());
}
}

class MyUtil {
private Integer age = 30;
public static String getFavoriteBook(){
return "Mahabharat";
}
public Integer getAge(){
return age;
}
}

输出

1
2
3
Mahabharat
30
-682408931

使用默认构造函数实例化Supplier

我们可以使用没有参数的构造函数来实例化Supplier,即默认构造函数。

找到Book类的构造函数参考。

1
Book::new

找到使用默认构造函数来实例化Supplier的例子。

SupplierWithConstructorRef.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Random;
import java.util.function.Supplier;

public class SupplierWithConstructorRef {
public static void main(String[] args) {
Supplier<Random> s1 = Random::new;
Random random = s1.get();
System.out.println(random.nextInt(10));

Supplier<Book> s2 = Book::new;
Book book = s2.get();
System.out.println(book.getBookName());
}
}

class Book {
private String bookName = "Mahabharat";
public String getBookName(){
return bookName;
}
}

输出

1
2
9
Mahabharat

自定义Supplier功能接口

我们可以使用@FunctionalInterface注解创建一个自定义的Supplier功能接口。

我们的Supplier不接受参数,但返回一个通用类型的值。

CustomSupplierDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Random;

@FunctionalInterface
interface MySupplier<T> {
T fetch();
}

public class CustomSupplierDemo {
public static void main(String[] args) {
//Using Lambda Expression
MySupplier<String> s1 = () -> "Hello World!";
System.out.println(s1.fetch());

//Using Method Reference
Random random = new Random();
MySupplier<Integer> s2 = random::nextInt;
System.out.println(s2.fetch());

//Using Constructor
MySupplier<Random> s3 = Random::new;
Random rdm = s3.fetch();
System.out.println(rdm.nextInt(10));
}
}

输出

1
2
3
Hello World!
521143516
6

BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier

Java提供了以下功能接口,用于特定数据类型的Supplier

BooleanSupplier:Supplier返回Boolean数据类型。它的方法是getAsBoolean()

IntSupplier:Supplier返回Integer数据类型。它的方法是getAsInt()

LongSupplier:Supplier返回Long数据类型。它的方法是getAsLong()

DoubleSupplier:Supplier返回Double数据类型。它的方法是getAsDouble()

下面是代码示例

SpecificDataTypeSupplier.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Random;
import java.util.function.BooleanSupplier;
import java.util.function.DoubleSupplier;
import java.util.function.IntSupplier;
import java.util.function.LongSupplier;

public class SpecificDataTypeSupplier {
public static void main(String[] args) {
int age = 30;
BooleanSupplier bs = () -> age > 20;
System.out.println(bs.getAsBoolean());

Random random = new Random();
IntSupplier is = random::nextInt;
System.out.println(is.getAsInt());

LongSupplier ls = random::nextLong;
System.out.println(ls.getAsLong());

DoubleSupplier ds = random::nextDouble;
System.out.println(ds.getAsDouble());
}
}

输出

1
2
3
4
true
-429015737
5525406112169000010
0.7553680537299522

Java Supplier与Consumer区别

Java``SupplierConsumer都是功能接口。

Supplier表示结果的提供者,该结果返回一个对象且不接受任何参数,而Consumer表示一个操作,其接受单个输入参数且不返回任何结果。

Supplier功能接口的方法。

1
T get()

Consumer功能界面的方法。

1
void accept(T t)

示例

SupplierConsumerDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.function.Consumer;
import java.util.function.Supplier;

public class SupplierConsumerDemo {
public static void main(String[] args) {
Supplier<String> s = Country::getPMName;
Consumer<String> c = Country::printMessage;
c.accept(s.get());
}
}

class Country {
public static String getPMName() {
return "Narendra Modi";
}
public static void printMessage(String msg) {
System.out.println(msg);
}
}

输出

1
Narendra Modi

参考文献

【1】Interface Supplier【2】Java Functional Interface【2】Java Supplier Example

来自: 【Java 8 新特性】Java Supplier示例-CSDN博客