Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to generalize a comparison in Java code

Say I have a Filter interface

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

Which can have different implementations (one such below)

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;
        };
    }
}

In some cases I would like to perform an inclusive comparison and other times I would like to perform an exclusive comparison, however in the above form, I will need to repeat the switch expression for every single implementation.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is there an alternative way that I can generalize this pattern for all implementations so as not to have to repeat the code in the switch statement?

Tried to user another interface but ended up in a loop of repeating code again.

>Solution :

Note that your Filter is basically identical to java.util.function.Predicate, so we can just use that. You also don’t need a subclass of Filter; just use lambdas.

In your example, the inclusive/exclusive choice travels with the filter, so all you have to do is define two factories:

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;
}

If you want to use data, rather than the method name, to select inclusive/exclusive, you can do that with the switch in just one place:

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;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading