我正在学习可选课程。我只是对方法Optional.ifPresent(Consumer<? super T> consumer)
的正确使用感到困惑。
我在一个项目上看到了这个例子:
Optional.ofNullable(user.getIdentifiantAAA())
.ifPresent(id -> identifiants.add(new Identifiant(id, IdentifiantType.AAA));
恕我直言,它的可读性不如:
if (user.getIdentifiantAAA() != null) {
identifiants.add(user.getIdentifiantAAA());
}
可能包含也可能不包含非null值的容器对象。如果一个 值存在,isPresent()将返回true,get()将返回 值。
我觉得示例的Optional.ifPresent的使用破坏了该类的主要提议。仅使用isPresent方法创建Optional的实例,在这种情况下是否真的必要?
所以,我的问题是:应该将对象包装在Optional中,以使非null终止并使用方法Optional.ifPresent(Consumer<? super T> consumer)
执行代码吗?
答案 0 :(得分:2)
Optional<T>
并不意味着可以代替简单的if
检查,第一个示例肯定不是 not 创建Optional<T>
的原因。
仅当您执行以下扩展逻辑时,才使用ifPresent
:
Optional.ofNullable(user.getIdentifiantAAA())
.map(...)
.ifPresent(...);
或者如果您正在使用的值已经是Optional<T>
,则可能是方法调用或某些计算返回的Optional<T>
。
答案 1 :(得分:2)
在Optional the mother of all bike sheds的@Devoxx US演讲中,Oracle的Stuart Marks详细介绍了可选的有用方式(以及有关可选的其他方面)
有用的主要用例是退货,就像@Paul Rooney提到的那样
答案 2 :(得分:1)
我敢说方法Consumer
所采用的ifPresent
没有要求。我个人认为这行没错:
.ifPresent(id -> identifiants.add(new Identifiant(id, IdentifiantType.AAA));
这里的问题是将user.getIdentifiantAAA()
包裹在Optional
中只是为了使用其方法,这是一种不良做法,并且与this thread有关。
答案 3 :(得分:0)
不确定使用它的方法是否错误,但是我经常使用的一种方法是使用功能接口。
考虑以下代码:
#include <cstdint>
#include <iostream>
#include <random>
#include <vector>
#include <numeric>
#include <cmath>
#define func auto
func nCk(uint64_t n, uint64_t k) -> double { // computes binomial coefficient
if (k > n)
return 0.0;
if (k * 2ULL > n)
k = n - k;
if (k == 0.0)
return 1.0;
return exp(lgamma(n+1) - (lgamma(k+1) + lgamma(n-k+1)));
}
func PMF(uint64_t N, uint64_t K, uint64_t n, uint64_t k) -> double { // Hypergeometric distribution PMF
return nCk(K, k) * nCk(N - K, n - k) / nCk(N, n);
}
func sample_hyper(int N, int K, int n, // sampling from Hypergeometric distribution
std::mt19937_64& rng,
std::vector<int>& nums) -> int {
int rc{ 0 };
for (int k = 0; k != n; ++k) {
std::uniform_int_distribution<int> uni{ k, N-1 };
auto s = uni(rng);
std::swap(nums[k], nums[s]);
rc += (nums[k] < K);
}
return rc;
}
func main() -> int {
auto rng = std::mt19937_64{1234567891ULL};
int N = 500; // compare with Wiki
int K = 50;
int n = 100;
auto nums = std::vector<int>( N );
std::iota(nums.begin(), nums.end(), 0); // array to shuffle, filled with 0, 1, 2, 3 ... sequence
auto h = std::vector<int>( K, 0 ); // histogram
int NT = 100000; // number of trials
for(int k = 0; k != NT; ++k) {
int q = sample_hyper(N, K, n, rng, nums);
h[q] += 1; // count it
}
for (int k = 0; k != 20; ++k) { // and print it
double e = double(h[k]) / double(NT);
std::cout << k << " " << e << " " << PMF(N, K, n, k) << '\n';
}
return 0;
}
使用“可选”,我可以使它更简洁:
java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myApp -jar myApp.jar -agentpath:/opt/cdbg/cdbg_java_agent.so=--cdbg_extra_class_path=/mydirtoclassdirectory
答案 4 :(得分:-1)
这实际上取决于偏好。 0:
displayName: "XXXXXXXXXXXXXXXX"
email: "XXXXXXXXXXXXXXXX"
phoneNumber: null
photoURL: "XXXXXXXXXXXXXXXX"
providerId: "google.com"
uid: "XXXXXXXXXXXXXXXX"
的全部要点是像在Optional
中一样处理null
。