Java 8有许多可选类,例如OptionalDouble
,OptionalInt
,OptionalLong
。
使用相同类型的可选值有一种很好的操作方式吗?也就是说,我希望能够做到:
OptionalDouble d1 = OptionalDouble.of(1.);
OptionalDouble d2 = OptionalDouble.of(2.);
OptionalDouble d3 = OptionalDouble.of(3.);
OptionalDouble result = d1.add(d2).multiply(d3);
当然,如果其中任何一个“空”,结果应为空。在谷歌搜索了一下后,我找到了一些人们正在使用这些函数的代码示例(例如add
),但它不是API的一部分(不再是?)。
答案 0 :(得分:3)
怪异。引用Optional
有map
方法,您可以使用类似于您想要的方法,但它似乎不存在于原始选项中。我相信您目前唯一的办法是使用OptionalDouble::isPresent
或OptionalDouble::ifPresent
。
或者您可以定义自己的帮助器add
方法或定义自己的OptionalDouble
类以包含这些方法。
答案 1 :(得分:3)
你可以自己创建一个封装OptionalDouble
的实现,这里要考虑的一个非常重要的事情是你的封装类应该是不可变的,以防止混淆,因为OptionalDouble
本身是不可变的。
为了便于阅读,自己的实现优于静态方法。
我继续创造了自己的,尽可能采用最基本的行为:
public class OptionalDoubleImproved {
private static final OptionalDoubleImproved EMPTY = OptionalDoubleImproved.of(OptionalDouble.empty());
private final OptionalDouble optionalDouble;
private OptionalDoubleImproved(final OptionalDouble optionalDouble) {
this.optionalDouble = Objects.requireNonNull(optionalDouble);
}
public static OptionalDoubleImproved of(final OptionalDouble optionalDouble) {
return new OptionalDoubleImproved(optionalDouble);
}
public OptionalDoubleImproved applyFunction(final DoubleBinaryOperator operator, final OptionalDouble operand) {
Objects.requireNonNull(operator);
Objects.requireNonNull(operand);
if (!optionalDouble.isPresent() || !operand.isPresent()) {
return EMPTY;
}
return OptionalDoubleImproved.of(OptionalDouble.of(operator.applyAsDouble(optionalDouble.getAsDouble(), operand.getAsDouble())));
}
public OptionalDouble get() {
return optionalDouble;
}
@Override
public int hashCode() {
int hash = 7;
hash = 53 * hash + Objects.hashCode(this.optionalDouble);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final OptionalDoubleImproved other = (OptionalDoubleImproved) obj;
if (!Objects.equals(this.optionalDouble, other.optionalDouble)) {
return false;
}
return true;
}
@Override
public String toString() {
return "OptionalDoubleImproved[" + optionalDouble + "]";
}
}
然后可以用作:
OptionalDouble d1 = OptionalDouble.of(1.);
OptionalDouble d2 = OptionalDouble.of(2.);
OptionalDouble d3 = OptionalDouble.of(3.);
OptionalDouble result = OptionalDoubleImproved.of(d1)
.applyFunction((a, b) -> a + b, d2)
.applyFunction((a, b) -> a * b, d3)
.get();
答案 2 :(得分:3)
Optional
的主要目的是代表一个函数return value that might be absent。
拥有流的原始特化是为了避免装箱/拆箱开销。对于OptionalInt
和朋友来说,这是一个不可避免的拳击水平(如果它们不存在会更糟,因为替代方案将是Optional<Integer>
),但意图是为了谁处理返回值以立即对其进行解包(或者提供默认值或者如果它不存在则抛出异常),然后从那时起处理实际的原语。
支持所有其他API对可选基元进行算术,比较等会增加更多的API膨胀。与Java中已经存在的完美精细的算术表达式语法相比,使用它会导致混乱,缓慢的代码,相当不利。简而言之,在可选基元上添加一组操作并不被认为是有用的。
答案 3 :(得分:2)
我会使用普通double
double d1 = 1, d2 = 2, d3 = 3;
if (condition)
d1 = Double.NaN;
double result = (d1 + d2) * d3; // if any double is NaN, the result is NaN
不仅更快更短,而且更简单。