供应商会提高性能或者在抽象层面上带来好处吗?
不会。 Supplier
用于延迟执行,即您指定一个功能(代码),当使用时它将运行。以下示例演示了差异:
import java.time.LocalDateTime;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) throws InterruptedException {
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
Supplier<LocalDateTime> dateSupplier = LocalDateTime::now;
Thread.sleep(5000);
System.out.println(ldt);
System.out.println(dateSupplier.get());
Thread.sleep(5000);
System.out.println(ldt);
System.out.println(dateSupplier.get());
}
}
一个样例运行的输出结果:
2021-04-11T00:04:06.205105
2021-04-11T00:04:06.205105
2021-04-11T00:04:11.211031
2021-04-11T00:04:06.205105
2021-04-11T00:04:16.211659
另一个有用的案例:
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Hello", "B2C", "World", "Stack Overflow", "is", "a", "gr8", "platform");
Stream<String> stream = list.stream()
.filter(s -> s.length() <= 5)
.map(s -> s.substring(1));
System.out.println(stream.anyMatch(s -> Character.isLetter(s.charAt(0))));
System.out.println(stream.anyMatch(s -> Character.isDigit(s.charAt(0))));
}
}
输出:
true
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
at java.base/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:528)
at Main.main(Main.java:13)
输出结果不言自明。一个丑陋的解决方法是每次创建一个新的
Stream
,如下所示:
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Hello", "B2C", "World", "Stack Overflow", "is", "a", "gr8", "platform");
System.out.println(list.stream().filter(s -> s.length() <= 5).map(s -> s.substring(1))
.anyMatch(s -> Character.isLetter(s.charAt(0))));
System.out.println(list.stream().filter(s -> s.length() <= 5).map(s -> s.substring(1))
.anyMatch(s -> Character.isDigit(s.charAt(0))));
}
}
现在,看看您如何使用 Supplier
来更加干净地完成它:
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Hello", "B2C", "World", "Stack Overflow", "is", "a", "gr8", "platform");
Supplier<Stream<String>> streamSupplier = () -> list.stream()
.filter(s -> s.length() <= 5)
.map(s -> s.substring(1));
System.out.println(streamSupplier.get().anyMatch(s -> Character.isLetter(s.charAt(0))));
System.out.println(streamSupplier.get().anyMatch(s -> Character.isDigit(s.charAt(0))));
}
}
输出:
true
true
s2
会在赋值时记录"现在"的时间点。s1.get()
会在调用get()
方法时记录"现在"的时间点。如果你将Supplier
传递到某个需要使用它的地方,那么这两个时间点可能不一样。如果稍后再次调用s1.get()
,你将再次获得一个不同的时间。 - khelwood