[英]Is there a better way of handling multiple null checks in Java?
我有以下代码
Set<Product> getallProducts(){
Product p = getProduct(brand, price);
Product p1 = getProduct(brand, price, location);
Product p2 = getProduct(brand, price, qty);
Set<SuperProducts> superProducts = new HashSet<>;
if(p!=null){
SuperProduct sp = getSuperProduct(p)
superProducts.add(sp)
}
if(p1!=null){
SuperProduct sp1 = getSuperProduct(p1)
superProducts.add(sp)
}
if(p2!=null){
SuperProduct sp2 = getSuperProduct(p2)
superProducts.add(sp2)
}
}
有没有明确的方法来处理 p!=null, p2!=null, p1 !=null。 我可以将 p,p1,p2 添加到列表中并按如下方式遍历它,但我正在寻找一种比将产品添加到列表然后遍历它们更便宜的方法。? 另外,我想知道每次检查 null 是否比添加到列表并遍历它更昂贵?
List<Product> products = new ArrayList<>():
products.add(p);
products.add(p1);
products.add(p2);
and
for(Product p:products){
// and adding to superProducts
}
您可以使用Stream.of
然后filter
为:
return Stream.of(p1, p2, p3).filter(Objects::nonNull)
.map(this::getSuperProduct)
.collect(Collectors.toSet());
这是一种使用 Optional 的方法,不会比其他答案长多少,因为无论如何都需要创建每个 Product 对象。
Set<Product> getallProducts() {
Set<SuperProducts> superProducts = new HashSet<>;
Optional.ofNullable(getProduct(brand, price))
.ifPresent(prod -> superProducts.add(new SuperProduct(prod)));
Optional.ofNullable(getProduct(brand, price, location))
.ifPresent(prod -> superProducts.add(new SuperProduct(prod)));
Optional.ofNullable(getProduct(brand, price, qty))
.ifPresent(prod -> superProducts.add(new SuperProduct(prod)));
return superProducts;
}
如果您正在寻找执行此操作的最佳方式,请坚持使用您当前的方式。 您的解决方案很冗长,但可能尽可能有效。 毫无疑问,您的代码比其他替代方案更容易理解。
如果您正在寻找使用更少代码行的解决方案,您可以使用流和过滤器来实现这一点,或者通过创建Product
引用和迭代的数组或列表来实现。 然而,这些解决方案都需要创建临时数据结构并且效率大大降低。
请注意,如果getSuperProduct(p)
调用是由 JIT 编译器内联的,那么它可能能够优化掉调用中发生的null
隐式测试。
另外,我想知道每次检查 null 是否比添加到列表并遍历它更昂贵?
我想你会发现情况正好相反。 在任何一种情况下,您都需要进行空检查(或不...见上文)。 当你尝试使用一个列表、数组或流时,你有创建数据结构的开销(一个或多个新的堆对象来创建和初始化),当你到达列表的末尾时你有测试的开销/阵列/流。
最后要注意的一件事是,像这样的代码的效率通常是无关紧要的。 我们可能在谈论不到 100 条指令的差异; 即小于 1 微秒的差异。 与应用程序正在执行的其他操作相比,这可能是微不足道的。
鉴于相同的代码序列重复 3 次,我将编写一个实用方法:
private void addSuper(Product p, Set<SuperProduct> s) {
if (p != null)
s.add(getSuperProduct(p));
}
进而
Set<SuperProduct> superProducts = new HashSet<>();
addSuper(getProduct(brand, price), superProducts);
addSuper(getProduct(brand, price, location), superProducts);
addSuper(getProduct(brand, price, qty), superProducts);
我在进行这种重构时主要关注的不是“非空测试”,而是原始内容的重复性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.