假设我有一个Filter接口

public interface Filter {
   public boolean satisfies(Earthquake earthquake)
}

它可以有不同的实现(如下所示)

public final class MagnitudeFilter implements Filter {

    private final double minimumMagnitude;
    private final double maximumMagnitude;
    private final ComparisonStrategy strategy;

    public MagnitudeFilter(double minimumMagnitude, double maximumMagnitude, ComparisonStrategy strategy) {
        this.minimumMagnitude = minimumMagnitude;
        this.maximumMagnitude = maximumMagnitude;
        this.strategy = strategy;
    }

    @Override
    public boolean satisfies(Earthquake earthquake) {
        return switch (strategy) {
            case EXCLUSIVE -> earthquake.magnitude() > minimumMagnitude &&
                earthquake.magnitude() < maximumMagnitude;
            case INCLUSIVE -> earthquake.magnitude() >= minimumMagnitude &&
                earthquake.magnitude() <= maximumMagnitude;
        };
    }
}

在某些情况下,我希望执行inclusive比较,而在其他情况下,我希望执行exclusive比较,但是在上面的形式中,我需要 for each 实现重复switch表达式.

是否有其他方法可以将此模式推广到所有实现,从而不必重复Switch语句中的代码?

试图使用另一个界面,但最终再次陷入了重复代码的循环.

推荐答案

注意,你的Filter基本上等同于java.util.function.Predicate,所以我们可以使用它.您也不需要Filter的子类;只需使用lambdas即可.

在您的示例中,包含/排除选项与筛选器一起传递,因此您所要做的就是定义两个工厂:

Predicate<Earthquake> rangeInclusive(double min, double max) { 
    return e -> e.magnitude() > min && e.magnitude() <= max;
}

Predicate<Earthquake> rangeExclusive(double min, double max) { 
    return e -> e.magnitude() > min && e.magnitude() < max;
}

如果您希望使用数据而不是方法名称来 Select 包含/排除,则只需在一个位置使用switch 即可:

Predicate<Earthquake> range(double min, double max, ComparisonStrategy strat) { 
    return switch (strat) { 
        case INCLUSIVE -> e -> e.magnitude() > min && e.magnitude() <= max;
        case EXCLUSIVE -> e -> e.magnitude() > min && e.magnitude() < max;
}

Java相关问答推荐

我可以在regex中的字符类中放置断言吗?

AlarmManager没有在正确的时间发送alert

在spring—data中自动发现native—sql查询期间遇到重复的SQL别名[id]

Java中如何根据Font.canDisplay方法对字符串进行分段

我无法获取我的Java Spring应用程序的Logback跟踪日志(log)输出

这是什么Java构造`(InputStream Is)->;()->;{}`

Spark忽略Iceberg Nessie目录

尽管通过中断请求线程死亡,但线程仍将继续存在

迁移到Java 17后,日期显示不准确

在Java 15应用程序中运行Java脚本和Python代码

Java Telnet客户端重复的IAC符号

Java.lang.invke.LambdaConversionException:实例方法InvokeVirtual的参数数量不正确

如何在透视表中添加对计数列的筛选?

EXCEL中的公式单元格显示#NAME?

从泛型枚举创建EnumMap

有没有办法知道在合并中执行了什么操作?

模拟JUnit未检测到返回字符串的方法的任何声纳覆盖

Cucumber java-maven-示例表-未定义一步

Java 21内置http客户端固定运营商线程

如何使用我的RLE程序解决此问题