Java执行字符串表达式 ScriptEngine应用,并结合StringSubstitutor 替换占位符

本文介绍了如何在Java中利用ScriptEngine执行JavaScript表达式来解决Java自身无法直接计算的问题。同时,结合Apache Commons的StringSubstitutor,实现占位符替换,以完成对数据库中保存表达式的处理。提供了相关链接以供深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载内容:

今天遇到了一个需要将数据库中保存的表达式,替换其中的字符,并计算出值,java是不能直接计算的例如: 

double d = (3+5-(2-4)*2)/24;没有问题  
  
但是:遇到   "(3+5-(2-4)*2)/24" 字符串的格式,就不能使用了  

java是无法解决,但是javaScript中有一个eval函数是可以执行的,所以,可以通过其他途径执行javaScript就可以做到,而ScriptEngine是java的一个javaScript实现类,所以就找到了方法,详细方法见下 

public class MapJ {
	private String key; // 替换的编号
	private String value; // 值
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public MapJ(String key, String value) {
		super();
		this.key = key;
		this.value = value;
	}
	public MapJ() {
		super();
	}
}


// 实现类
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JavaScript {

    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    
    public Double getMathValue(List<MapJ> map,String option) {
    	double d = 0;
		try {
			for (int i=0; i<map.size(); i++) {
				MapJ mapj = map.get(i);
				option = option.replaceAll(mapj.getKey(), mapj.getValue());
			}
			Object o = engine.eval(option);
			d = Double.parseDouble(o.toString());
		} catch (ScriptException e) {
			System.out.println("无法识别表达式");
			return null;
		}
		return d;
    }
}


public class JavaScriptTest {

	public static void main(String[] args) {

		String sbt = "(B+D-(A-C)*A)/F";
		List<MapJ> all = new ArrayList<MapJ>();
		all.add(new MapJ("A","2"));
		all.add(new MapJ("B","3"));
		all.add(new MapJ("C","4"));
		all.add(new MapJ("D","5"));
		all.add(new MapJ("F","24"));

		JavaScript js = new JavaScript();
		Double d = js.getMathValue(all, sbt);
		if (d == null) {
			System.out.println("无法计算这个表达式");
		} else {
			System.out.println(d*100+"%");
		}
	}
}

通过以上的方法即可实现此方法。

50.0%

 

切换为:结合StringSubstitutor 替换占位符

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

public class JavaScript {

    public static final ScriptEngineManager SCRIPT_ENGINE_MANAGER = new ScriptEngineManager();
    public static final ScriptEngine ENGINE;

    static {
        ENGINE = SCRIPT_ENGINE_MANAGER.getEngineByName("JavaScript");
    }

    public Double getMathValue(String option) {
        double d;
        try {
            d = (double) ENGINE.eval(option);

            // ScirptEngine.eval() 方法,执行表达式,可以判断表达式对错,返回true or false
            if ("true".equals(ENGINE.eval(d + ">0.4").toString())) {
                System.out.println("结果比0.4大");
            }
        } catch (ScriptException e) {
            System.out.println("无法识别表达式");
            return null;
        }
        return d;
    }
}


public class TestMain {
    public static void main(String[] args) {

        Map valuesMap = new HashMap(5);
        valuesMap.put("A", "2");
        valuesMap.put("B", "3");
        valuesMap.put("C", "4");
        valuesMap.put("D", "5");
        valuesMap.put("F", "24");
        // 修改
        String sbt = "(${B}+${D}-(${A}-${C})*${A})/${F}";
        
        // 结合StringSubstitutor 替换占位符
        StrSubstitutor sub = new StrSubstitutor(valuesMap);
        // 自动根据valuesMap的key,将value替换到表达式中
        String resolvedString = sub.replace(sbt);

        JavaScript js = new JavaScript();
        Double d = js.getMathValue(resolvedString);
        if (d == null) {
            System.out.println("无法计算这个表达式");
        } else {
            System.out.println(d * 100 + "%");
        }
    }
}
结果比0.4大
50.0%

 

Apache commons StringSubstitutor 替换占位符介绍:https://blog.youkuaiyun.com/weixin_41888813/article/details/90481607


参考来源:

https://ruyuntao.iteye.com/blog/406935

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值