java8 函数式编程 Supplier 类 supplier如何使用 supplier类作用
1. Supplier代码:
package java.util.function;
/**
* Represents a supplier of results.
*
* <p>There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #get()}.
*
* @param <T> the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
2. use demo:
import java.util.UUID;
import java.util.function.Supplier;
public class Test {
public static void main(String[] args) {
String uuid = buildResult(() -> UUID.randomUUID().toString().replace("-", ""));
System.out.println(uuid);
}
public static String buildResult(Supplier<String> supplier) {
return supplier.get();
}
}
3. 在阅读rocketmq 源码中CommitLog类doAppend方法有如下一段代码,产生了疑问,为什么使用supplier?msgId 直接赋值不是很好吗?为何多此一举,使用supplier lambda包下这块代码
4. 大模型回答:
4.1. 延迟计算(Lazy Evaluation)
使用 Supplier
可以实现延迟计算,即只有在真正需要消息 ID 的时候才进行计算。这在以下场景中非常有用:
-
消息发送过程中的优化:在消息发送的过程中,可能并不需要立即生成消息 ID。使用
Supplier
,可以在消息真正需要被存储或处理时才生成 ID,避免了不必要的计算开销。 -
提高性能:如果消息在发送后很快被取消或过滤掉,那么生成消息 ID 的计算就可以被完全避免,从而提高系统性能。
-
通过doAppend方法主要为生成AppendMessageResult对象, 最外层使用了
CompletableFuture.supplyAsync()
方法,可以方便地将消息 ID 的生成操作异步化,避免阻塞主线程。
总结: 延迟计算,避免有其他异常,返回只包含错误信息的AppendMessageResult,msgId根本不需要了,此时计算出来msgId反而是一种性能浪费。只有在使用的时候,去生成msgId!