Home > Software engineering >  Convert comparison operator string representations to actual operators in java
Convert comparison operator string representations to actual operators in java

Time:07-14

Basically, I have some comparators as an enum:

public enum Comparator {
  EQ("="),
  GTE(">="),
  GT(">"),
  LT("<"),
  LTE("<=");
}

And what I want to be able to do is to actually compare two variables (doubles) using the values of these enums. Something like private boolean conditionPassed(double var1, double var2, Comparator comp) {...}.

Is there a way of interpreting these strings as actual comparison operators? Or is there a way of defining the enum differently to accomplish this?

CodePudding user response:

Here is a solution using lambas and a BiPredicate

public enum Comparator {

    EQ("=", (d1, d2) -> d1.doubleValue() == d2.doubleValue()),
    GTE(">=", (d1, d2) -> d1 >= d2);
    // ... other entries ...

    private final String operator;
    private final BiPredicate<Double, Double> evaluation;

    Comparator(String operator, BiPredicate<Double, Double> evaluation) {
        this.operator = operator;
        this.evaluation = evaluation;
    }

    public boolean evaluate(double var1, double var2) {
        return evaluation.test(var1, var2);
    }

    public String getOperator() {
        return operator;
    }

}

CodePudding user response:

Try this.

public enum Comparator {
    EQ("=", x -> x == 0),
    GTE(">=", x -> x >= 0),
    GT(">", x -> x > 0),
    LT("<", x -> x < 0),
    LTE("<=", x -> x <= 0),
    NE("!=", x -> x != 0);

    public final String display;
    public final IntPredicate predicate;

    private Comparator(String display, IntPredicate predicate) {
        this.display = display;
        this.predicate = predicate;
    }
    
    public boolean test(double left, double right) {
        return predicate.test(Double.compare(left, right));
    }
}

private boolean conditionPassed(double var1, double var2, Comparator comp) {
    return comp.test(var1, var2);
}

And

System.out.println(conditionPassed(0, 0, Comparator.EQ));   // true
System.out.println(conditionPassed(0, 0, Comparator.GTE));  // true
System.out.println(conditionPassed(0, 0, Comparator.GT));   // false
System.out.println(conditionPassed(0, 0, Comparator.LT));   // false
System.out.println(conditionPassed(0, 0, Comparator.LTE));  // true
System.out.println(conditionPassed(0, 0, Comparator.NE));   // false

CodePudding user response:

Well, this certainly isn't very sexy, but it supports both primitive values and objects that implement the comparable interface. Depending on the use case, it my not solve your problem. But this is how I might approach it.

double a = 111209.000;
double b = 111209.000;
System.out.println(EQ(a,b));
System.out.println(GTE(20,10));
System.out.println(!GTE(20,10));
System.out.println(LE(100000.f, 200000.f));
System.out.println(!GTE('A','B'));
System.out.println(!GTE("B","A"));

System.out.println(evaluate(20,30, ContainingClass::LE));               

public static <T> boolean evaluate(T a, T b, BiPredicate<T,T> pred) {
    return pred.test(a,b);
}

prints

true
true
false
true
true
false
true

The methods

public static <T extends Comparable<? super T>> boolean EQ(T a, T b) {
    return a.compareTo(b) == 0;
}
public static <T extends Comparable<? super T>> boolean GTE(T a, T b) {
    return a.compareTo(b) >= 0;
}
public static <T extends Comparable<? super T>> boolean LE(T a, T b) {
    return a.compareTo(b) <= 0;
}
...
...
...

  • Related