简体   繁体   English

如何在Java中将字符串转换为运算符

[英]How to convert string to operator in java

I want to convert some String to an operator like this: 我想将一些String转换为这样的运算符:

int value = 1;
int valueToCompare = 3;
String operation = "<";

if (value operation valueToCompare) {
    // some operation       
}

How do I convert a variable operation into an operator? 如何将变量操作转换为运算符?

you may try this: 您可以尝试以下方法:

import java.util.*;

interface Operator {
  boolean compare(int a, int b);
}

class Launch
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Map<String, Operator> opMap = new HashMap<String, Operator>();
        opMap.put(">", new Operator() {
            @Override public boolean compare(int a, int b) {
                return a > b;
            }
        });
        opMap.put("<", new Operator() {
            @Override public boolean compare(int a, int b) {
                return a < b;
            }
        });
        opMap.put("==", new Operator() {
            @Override public boolean compare(int a, int b) {
                return a == b;
            }
        });
        String op = ">";
        int i = 4, j = 5;
        boolean test = opMap.get(op).compare(i, j);
        System.out.printf("test: %b, i: %d, op: %s, j: %d\n", test, i, op, j);
            //prints: test: false, i: 4, op: >, j: 5
    }
}

Sounds like you need a switch based around a string (for Java 7 and above - otherwise simple use if / else ), and a set of Comparator objects eg 听起来您需要基于字符串开关 (对于Java 7及更高版本-否则, if使用/ else则简单使用),以及一组Comparator对象,例如

switch (operation) {
   case ">" : return new GreaterThanComparator();

or 要么

if (operation.equals(">")) {
   return new GreaterThanComparator();
}

where GreaterThanComparator implements the Comparator interface. 其中GreaterThanComparator实现Comparator接口。 The class you've created implements your comparison functionality and could do a lot more besides. 您创建的类可以实现比较功能,并且还可以做更多的事情。 It's the closest Java has to the encapsulation of a function. 它是Java最接近函数封装的地方。

Note that the Comparator above can be used directly in Java collections in order to perform sorting etc. 请注意,上面的Comparator可以直接在Java集合中使用,以便执行排序等。

You could use lookup tables (eg a Map of String / Comparators ) or similar if you have a lot of these comparisons to make. 如果您要进行很多比较,则可以使用查找表(例如, String / Comparators Map )或类似表。 I think the important part of the above is the encapsulation of the behaviour via the Comparator object. 我认为上面的重要部分是通过Comparator对象封装行为。

An alternative is to use the scripting engine built into Java and parse (say) Javascript statements. 一种替代方法是使用Java内置的脚本引擎并解析(例如)Javascript语句。 That's perhaps more work, but certainly a more extensible solution. 那也许是更多的工作,但肯定是一个更可扩展的解决方案。 Note that you're not limited to Javascript, and a number of scripting languages exist, including Beanshell, Jython etc. 请注意,您不仅限于Javascript,还存在许多脚本语言,包括Beanshell,Jython等。

Your approach will never work in Java. 您的方法永远无法在Java中使用。 Instead you may define your own enum which perform the proper boolean operation like this: 相反,您可以定义自己的enum ,以执行正确的布尔操作,如下所示:

public static void main(String[] args) {
    boolean result = Operator.parseOperator("==").apply(2, 2);
}

enum Operator {

    LESS("<") {
        @Override public boolean apply(int left, int right) {
            return left < right;
        }
    },
    EQUAL("==") {
        @Override public boolean apply(int left, int right) {
            return left == right;
        }
    };

    private final String operator;

    private Operator(String operator) {
        this.operator = operator;
    }

    public static Operator parseOperator(String operator) {
        for (Operator op : values()) {
            if (op.operator.equals(operator)) return op;
        }
        throw new NoSuchElementException(String.format("Unknown operator [%s]", operator));
    }

    public abstract boolean apply(int left, int right);
}

Create a custom method which does it for you.. 创建一个为您执行此操作的自定义方法。

Something like this 像这样

private static boolean parseExpression(int number1, String operator, int number2)
{
    if ("<".equals(operator)) {
        return number1 < number2;
    } else if (">".equals(operator)) {
        return number1 > number2;
    } else if ("<=".equals(operator)) {
        return number1 <= number2;
    } else if (">=".equals(operator)) {
        return number1 >= number2;
    } else if ("==".equals(operator)) {
        return number1 == number2;
    } else { 
        throw new IllegalArgumentException("Invalid operator");
    }
}

private static boolean parseExpression(double number1, String operator, double number2)
{
    if ("<".equals(operator)) {
        return Double.compare(number1, number2) == -1;
    } else if (">".equals(operator)) {
        return Double.compare(number1, number2) == 1;
    } else if ("<=".equals(operator)) {
        return Double.compare(number1, number2) <= 0;
    } else if (">=".equals(operator)) {
        return Double.compare(number1, number2) >= 0;
    } else if ("==".equals(operator)) {
        return Double.compare(number1, number2) == 0;
    } else if ("!=".equals(operator)) {
        return Double.compare(number1, number2) != 0;
    } else { 
        throw new IllegalArgumentException("Invalid operator");
    }
}

If you don't want to use a comparator, it's something "simple" but should work. 如果您不想使用比较器,那是“简单”的事情,但应该可以使用。 For double/floats should do a bit more of work anyway 对于双/浮点无论如何应该做更多的工作


PS with Enums you could do something very elegant. PS与Enums可以做得非常优雅。 With Java7 you can use switch-strings too. 使用Java7,您也可以使用switch-strings

最简单的方法是一连串的if-else语句,检查运算符是什么,然后执行数学表达式。

You can use ScriptEngine for that, works for any other JavaScript expressions also : 您可以使用ScriptEngine,也可以用于任何其他JavaScript表达式:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");


int value = 1;
int valueToCompare = 3;
String operation = "<";

if ((Boolean)engine.eval("" + value + operation + valueToCompare)) {
    System.out.println("Here we are.");  
}

You could try using a switch statement: 您可以尝试使用switch语句:

switch(operation) {
    case "<" : //code here
        break;
    case ">" : //code here
        break;
    case "==" : //code here
        break;
}

It is not directly possible, you'll have to write some code. 这不是直接可能的,您必须编写一些代码。 One possibility is using enums: 一种可能是使用枚举:

enum Operation {
    LESS_THAN("<") {
        @Override int compare(int o1, int o2) {
            return o1 - o2;
        }
    },
    ...;

    private final String operator;
    private Operation(final String operator) {
        this.operator = operator;
    }

    private static final Map<Operation, String> MAP = new HashedMap<Operation, String>();
    static {
        for (final Operation op: values()) MAP.put(op.operator, op);
    }

    public static Operation valueOf(final String op) {
        return MAP.get(op);
    }
}

Usage example: 用法示例:

int cmp = Operation.valueOf(operation).compare(value, valueToCompare);

Answer 回答

For completeness¸I would like to add that there already exists a lot of code for this. 为了完整起见,我想补充一点,就是已经有很多代码了。 I know you asked a very specific question, but the general answer would be to look at existing solutions how that is done. 我知道您问了一个非常具体的问题,但是一般的答案是查看现有解决方案的完成方式。

Example: 例:

Built-in method for evaluating math expressions in Java Java中评估数学表达式的内置方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM