Java 11基于枚举值选择要应用于流的方法



我有以下枚举。

public enum AggregationType
{
MIN,
MAX,
AVERAGE
}

让我们假设我有一个函数,我在其中传递类似的枚举值

public Float someFunction(final AggregationType enum) {
return (float) provides.stream()
.mapToDouble(this::someFunc)
.average()
.orElse(-1);

}

我想在基于枚举值的流上应用这个.average((.min((.max((方法。

我怎样才能做到这一点?我不想在someFunction中使用简单的switch函数,而是在这个return语句中使用。

所以我想要一些类似的东西

public Float someFunction(final AggregationType enum) {
return (float) provides.stream()
.mapToDouble(this::someFunc)
.decideWhichMethodShouldBeUsed()
.orElse(-1);

}

其中decideWhichMethodShouldBeUsed((根据enum决定使用哪个函数。

何时可以将enum类型更改为

public enum AggregationType {
MIN(DoubleStream::min),
MAX(DoubleStream::max),
AVERAGE(DoubleStream::average);
public final Function<DoubleStream, OptionalDouble> operation;
AggregationType(Function<DoubleStream, OptionalDouble> f) {
operation = f;
}
}

你可以实现类似的方法

public Float someFunction(final AggregationType aType) {
return (float)aType.operation.apply(provides.stream().mapToDouble(this::someFunc))
.orElse(-1);
}

如果更改枚举类型不是一个选项,则必须在想要实现someFunction的地方处理到实际操作的映射,例如

private static final Map<AggregationType,Function<DoubleStream, OptionalDouble>> OPS;
static {
EnumMap<AggregationType,Function<DoubleStream, OptionalDouble>>
m = new EnumMap<>(AggregationType.class);
m.put(AggregationType.MIN, DoubleStream::min);
m.put(AggregationType.MAX, DoubleStream::max);
m.put(AggregationType.AVERAGE, DoubleStream::average);
OPS = Collections.unmodifiableMap(m);
}
public Float someFunction(final AggregationType aType) {
return (float)OPS.get(aType).apply(provides.stream().mapToDouble(this::someFunc))
.orElse(-1);
}

您也可以使用switch语句,但它相当笨重

public Float someFunction(final AggregationType aType) {
DoubleStream ds = provides.stream().mapToDouble(this::someFunc);
OptionalDouble d;
switch(aType) {
case MAX: d = ds.max(); break;
case MIN: d = ds.min(); break;
case AVERAGE: d = ds.average(); break;
default: throw new AssertionError();
}
return (float)d.orElse(-1);
}

当您使用最新的Java版本时,情况会变得更好,因此,您可以使用switch表达式:

public Float someFunction(final AggregationType aType) {
DoubleStream ds = provides.stream().mapToDouble(this::someFunc);
return (float)(switch(aType) {
case MAX -> ds.max();
case MIN -> ds.min();
case AVERAGE -> ds.average();
}).orElse(-1);
}

只有当处理完所有enum常量时,编译器才接受此操作。然后,它将在后台生成一个等价于default -> throw new AssertionError();的代码,只要在编译完该代码后没有人更改enum类型,就永远不会在运行时使用该代码。

通常,只有第一种变体会迫使考虑向AggregationType添加新常量的开发人员也考虑处理相关的operation

最新更新