Java 8可选*值的操作。

时间:2014-05-01 19:18:33

标签: java java-8

Java 8有许多可选类,例如OptionalDoubleOptionalIntOptionalLong

使用相同类型的可选值有一种很好的操作方式吗?也就是说,我希望能够做到:

OptionalDouble d1 = OptionalDouble.of(1.);
OptionalDouble d2 = OptionalDouble.of(2.);
OptionalDouble d3 = OptionalDouble.of(3.);

OptionalDouble result = d1.add(d2).multiply(d3);

当然,如果其中任何一个“空”,结果应为空。在谷歌搜索了一下后,我找到了一些人们正在使用这些函数的代码示例(例如add),但它不是API的一部分(不再是?)。

4 个答案:

答案 0 :(得分:3)

怪异。引用Optionalmap方法,您可以使用类似于您想要的方法,但它似乎不存在于原始选项中。我相信您目前唯一的办法是使用OptionalDouble::isPresentOptionalDouble::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

不仅更快更短,而且更简单。