在 java 中将比较运算符字符串表示形式转换为实际运算符

Convert comparison operator string representations to actual operators in java

提问人:wonderv 提问时间:7/14/2022 更新时间:7/14/2022 访问量:180

问:

基本上,我有一些比较器作为枚举:

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

我希望能够做的是实际使用这些枚举的值来比较两个变量(双精度)。 类似 .private boolean conditionPassed(double var1, double var2, Comparator comp) {...}

有没有办法将这些字符串解释为实际的比较运算符?或者有没有办法以不同的方式定义枚举来实现这一点?

Java 比较

评论

1赞 PM 77-1 7/14/2022
Comporator 是一个现有的 Java 接口。帮自己一个忙,重命名你的.您可以在方法中用于实现实际比较。实现相等时,请记住,您需要使用 (not )。enumswitch===
1赞 Dawood ibn Kareem 7/14/2022
不要使用 switch。将枚举中的一个字段设为 .BiFunction<Double, Double, Boolean>
3赞 WJS 7/14/2022
为什么?您的用例是什么?正常的原始比较有什么问题?特别是因为这些运算符适用于所有数值类型。

答:

4赞 Volt4 7/14/2022 #1

这是一个使用 lambas 和 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;
    }

}

评论

0赞 WJS 7/14/2022
为什么要将 String 运算符传递给构造函数。不就叫吗?Comparator.EQ.evaluate(a,b)
0赞 user17233545 7/14/2022 #2

试试这个。

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

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
0赞 WJS 7/14/2022 #3

嗯,这当然不是很性感,但它支持基元值和实现可比接口的对象。根据用例,它不能解决您的问题。但这就是我可能处理它的方式。

double a = 111209.000;
double b = 111209.000;
System.out.println(EQ(a,b));
System.out.println(GE(20,10));
System.out.println(!GE(20,10));
System.out.println(LE(100000.f, 200000.f));
System.out.println(!GE('A','B'));
System.out.println(!GE("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);
}

指纹

true
true
false
true
true
false
true

方法

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 GE(T a, T b) {
    return a.compareTo(b) >= 0;
}
public static <T extends Comparable<? super T>> boolean GT(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;
}
...
...
...