转载:https://www.jb51.net/article/143967.htm

方法一:Java调用js方法执行:

/**
*
* @author: Longjun
* @Description: 将${money>=2000&&money<=4000}字符串截取成"money>=2000&&money<=4000",
* 然后判断一个数值字符串是否在此区间内
* @date:2016年3月21日 上午11:25:32
*/
public static Boolean isInclude(String elValue,String elString){
String el = elString.substring(elString.indexOf("{")+1, elString.indexOf("}"));
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
engine.put("money",elValue);
boolean eval = false;
try {
eval = (boolean) engine.eval(el);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return eval;
}

方法二:能够保证四则运算精度

/**
* @Project: BizRule
* @File: org.coffeesweet.util.MathExpress.java
* @Author: coffeesweet
* @Date: 2011-3-28
* @Description: 2011 coffeesweet Inc. All rights reserved.
*/
package org.coffeesweet.util;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author coffeesweet
* +,-,*,/四则运算的表达式逆波兰解析计算类,精确计算,应用BigDecimal类处理
* 支持负数,但规范除整个表达式第一个数为负数时可以不出现在'('后,其它表达式中间任何位置的
* 负数必须出现在'('后,即:用括号括起来。比如:-3+(-2+1)*10或-3+((-2)+1)*10或(-3)+(-2+1)*10或(-3)+((-2)+1)*10
*/
public class MathExpress {
/**
* +
*/
private final static String OP1 = "+";
/**
* -
*/
private final static String OP2 = "-";
/**
* *
*/
private final static String OP3 = "*";
/**
* /
*/
private final static String OP4 = "/";
/**
* ^
*/
// private final static String OP5 = "^";
/**
* %
*/
// private final static String OP6 = "%";
/**
* (
*/
private final static String OPSTART = "(";
/**
* )
*/
private final static String OPEND = ")";
/**
* !用来替代负数前面的'-'
*/
// private final static String NEGATIVESING = "!";
/**
* !用来替代负数前面的'+'
*/
// private final static String PLUSSING = "@";
/**
* '#'用来代表运算级别最低的特殊字符
*/
// private final static String LOWESTSING = "#";
//最原始的四则运算式
private String expBase;
//经过初始化处理后的四则运算式
private String expInited;
//精度
private int precision=10;
//取舍模式
private RoundingMode roundingMode=RoundingMode.HALF_UP;
//精度上下文
private MathContext mc;
//四则运算解析
private List<String> expList = new ArrayList<String>();
//存放逆波兰表达式
private List<String> rpnList = new ArrayList<String>();
public MathExpress(){
}
public MathExpress(String expBase) {
init(expBase,this.precision,this.roundingMode);
}
public MathExpress(String expBase,int precision,RoundingMode roundingMode){
init(expBase,precision,roundingMode);
}
public void init(String expBase,int precision,RoundingMode roundingMode){
this.expBase = expBase;
this.precision = precision;
this.roundingMode = roundingMode;
this.mc = new MathContext(precision,roundingMode);
this.expInited = initExpress(expBase);
StringTokenizer st = new StringTokenizer(this.expInited,"+-*/^%()",true);
while(st.hasMoreElements()){
this.expList.add(st.nextElement().toString().trim());
}
this.rpnList = initRPN(this.expList);
}
/**
* @return the expBase
*/
public String getExpBase() {
return expBase;
}
/**
* @param expBase the expBase to set
*/
public void setExpBase(String expBase) {
this.expBase = expBase;
}
/**
* @return the expInited
*/
public String getExpInited() {
return expInited;
}
/**
* @param expInited the expInited to set
*/
public void setExpInited(String expInited) {
this.expInited = expInited;
}
/**
* @return the precision
*/
public int getPrecision() {
return precision;
}
/**
* @param precision the precision to set
*/
public void setPrecision(int precision) {
this.precision = precision;
}
/**
* @return the roundingMode
*/
public RoundingMode getRoundingMode() {
return roundingMode;
}
/**
* @param roundingMode the roundingMode to set
*/
public void setRoundingMode(RoundingMode roundingMode) {
this.roundingMode = roundingMode;
}
/**
* @return the expList
*/
public List<String> getExpList() {
return expList;
}
/**
* @param expList the expList to set
*/
public void setExpList(List<String> expList) {
this.expList = expList;
}
/**
* @return the rpnList
*/
public List<String> getRpnList() {
return rpnList;
}
/**
* @param rpnList the rpnList to set
*/
public void setRpnList(List<String> rpnList) {
this.rpnList = rpnList;
}
/**
* @return the mc
*/
public MathContext getMc() {
return mc;
}
/**
* @param mc the mc to set
*/
public void setMc(MathContext mc) {
this.mc = mc;
}
/**
* 去除空白字符和在负号'-'前加'0',便于后面的StringTokenizer
* @param exp
* @return
*/
private static String initExpress(String exp){
String reStr = null;
reStr = exp.replaceAll("\\s", "");
if(reStr.startsWith("-")){
reStr = "0"+reStr;
}
reStr = reStr.replaceAll("\\(\\-", "(0-");
return reStr;
}
/**
* 是否是整数或是浮点数,但默认-05.15这种也认为是正确的格式
* @param str
* @return
*/
private boolean isNumber(String str){
Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$");
Matcher m = p.matcher(str);
boolean isNumber = m.matches();
return isNumber;
}
/**
* 设置优先级顺序()设置与否无所谓
* @param sign
* @return
*/
private int precedence(String str){
char sign = str.charAt(0);
switch(sign){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
case '%':
return 3;
case '(':
case ')':
// case '#':
default:
return 0;
}
}
/**
* 转变为逆波兰表达式
* @param strList
* @return
*/
public List<String> initRPN(List<String> strList){
List<String> returnList = new ArrayList<String>();
//用来存放操作符的栈
Stack stack = new Stack();
// stack.push(LOWESTSING);
int length = strList.size();
for(int i=0;i<length;i++ ){
String str = strList.get(i);
if(isNumber(str)){
returnList.add(str);
}else{
if(str.equals(OPSTART)){
//'('直接入栈
stack.push(str);
}else if(str.equals(OPEND)){
//')'
//进行出栈操作,直到栈为空或者遇到第一个左括号
while (!stack.isEmpty()) {
//将栈顶字符串做出栈操作
String tempC = stack.pop();
if (!tempC.equals(OPSTART)) {
//如果不是左括号,则将字符串直接放到逆波兰链表的最后
returnList.add(tempC);
}else{
//如果是左括号,退出循环操作
break;
}
}
}else{
if (stack.isEmpty()) {
//如果栈内为空
//将当前字符串直接压栈
stack.push(str);
}else{
//栈不空,比较运算符优先级顺序
if(precedence(stack.top())>=precedence(str)){
//如果栈顶元素优先级大于当前元素优先级则
while(!stack.isEmpty() && precedence(stack.top())>=precedence(str)){
returnList.add(stack.pop());
}
}
stack.push(str);
}
}
}
}
//如果栈不为空,则将栈中所有元素出栈放到逆波兰链表的最后
while (!stack.isEmpty()) {
returnList.add(stack.pop());
}
return returnList;
}
/**
* 计算逆波兰表达式
* @param rpnList
* @return
*/
public String caculate(List<String> rpnList){
Stack numberStack = new Stack();
int length=rpnList.size();
for(int i=0;i<length;i++){
String temp=rpnList.get(i);
if(isNumber(temp)){
numberStack.push(temp);
}else{
BigDecimal tempNumber1 = new BigDecimal(numberStack.pop(),this.mc);
BigDecimal tempNumber2 = new BigDecimal(numberStack.pop(),this.mc);
BigDecimal tempNumber = new BigDecimal("0",this.mc);
if(temp.equals(OP1)){
tempNumber=tempNumber2.add(tempNumber1);
}else if(temp.equals(OP2)){
tempNumber=tempNumber2.subtract(tempNumber1);
}else if(temp.equals(OP3)){
tempNumber=tempNumber2.multiply(tempNumber1);
}else if(temp.equals(OP4)){
tempNumber=tempNumber2.divide(tempNumber1,
precision,
roundingMode);
}
numberStack.push(tempNumber.toString());
}
}
return numberStack.pop();
}
/**
* 按照类的缺省参数进行计算
* @return
*/
public String caculate(){
return caculate(this.rpnList);
}
/**
* 数字条件表达式精确比较
* eg: "3.0>2" "1<5" "1==5" "1!=5" "(1.0+2)>3" "((-0.9+3)>=2. 1)"
* 不支持&&,||等连接符
* @param str
* @return
*/
public static boolean compareTo(String strParm){
boolean reBoolean = false;
boolean isParentheses = false;//标记是否有()括上整个字符串
String str = initExpress(strParm);
Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$");
Matcher m = p.matcher(str);
isParentheses = m.matches();
if(-1==str.indexOf(">=")&&-1==str.indexOf("<=")&&-1==str.indexOf("==")&&-1==str.indexOf("!=")){
if(-1==str.indexOf(">")&&-1==str.indexOf("<"))
throw new IllegalArgumentException("异常:条件表达式不正确!");
}
if(-1 != str.indexOf(">=")){
String[] strTemps = str.split(">=");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( -1 == r ){
reBoolean = false;
}else{
reBoolean = true;
}
}else if(-1 != str.indexOf("<=")){
String[] strTemps = str.split("<=");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( 1 == r ){
reBoolean = false;
}else{
reBoolean = true;
}
}else if(-1 != str.indexOf("==")){
String[] strTemps = str.split("==");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( 0 == r ){
reBoolean = true;
}else{
reBoolean = false;
}
}else if(-1 != str.indexOf("!=")){
String[] strTemps = str.split("!=");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( 0 != r ){
reBoolean = true;
}else{
reBoolean = false;
}
}else if((-1 != str.indexOf(">")) && (-1 == str.indexOf("="))){
String[] strTemps = str.split(">");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( 1 == r ){
reBoolean = true;
}else{
reBoolean = false;
}
}else if((-1 != str.indexOf("<")) && (-1 == str.indexOf("="))){
String[] strTemps = str.split("<");
if(isParentheses){
strTemps[0] = strTemps[0] + ")";
strTemps[1] = "(" + strTemps[1];
}
int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));
if( -1 == r ){
reBoolean = true;
}else{
reBoolean = false;
}
}
return reBoolean;
}
public static void main(String...args){
// MathExpress me = new MathExpress("-(-0.5+0.1)*10+2",10,RoundingMode.HALF_UP);
// System.out.println(me.getExpList());
// List<String> tempList = me.initRPN(me.getExpList());
// System.out.println(tempList);
// String resultStr = me.caculate(tempList);
// System.out.println(resultStr);
MathExpress me = new MathExpress("-(-1.5000000003+0.1)*10+2");
String resultStr = me.caculate();
BigDecimal bd = new BigDecimal(resultStr);
BigDecimal bd2 = bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(me.caculate());
System.out.println(bd.toString());
System.out.println(bd.scale());
System.out.println(bd2.toString());
System.out.println(bd2.scale());
// System.out.println("------------------------------------");
// Pattern p = Pattern.compile("^\\([\\s\\S]*\\)$");//匹配类似以'('开头')'结尾的字符串
// Matcher m = p.matcher("(2. 0>2.22)");
// System.out.println(m.matches());
boolean reBoolean = MathExpress.compareTo("((-8.0+3)>=2. 1)");
System.out.println(reBoolean);
}
/**
* 栈
*/
private class Stack {
LinkedList<String> stackList = new LinkedList<String>();
public Stack() {
}
/**
* 入栈
* @param expression
*/
public void push(String expression) {
stackList.addLast(expression);
}
/**
* 出栈
* @return
*/
public String pop() {
return stackList.removeLast();
}
/**
* 栈顶元素
* @return
*/
public String top() {
return stackList.getLast();
}
/**
* 栈是否为空
* @return
*/
public boolean isEmpty() {
return stackList.isEmpty();
}
}
}

方法三:https://blog.csdn.net/u012468264/article/details/56679802

java代码执行字符串中的逻辑运算方法的更多相关文章

  1. 第一章 Java代码执行流程

    说明:本文主要参考自<分布式Java应用:基础与实践> 1.Java代码执行流程 第一步:*.java-->*.class(编译期) 第二步:从*.class文件将其中的内容加载到内 ...

  2. 【Hadoop离线基础总结】通过Java代码执行Shell命令

    通过Java代码执行Shell命令 需求 在实际工作中,总会有些时候需要我们通过java代码通过远程连接去linux服务器上面执行一些shell命令,包括一些集群的状态管理,执行任务,集群的可视化界面 ...

  3. Java 代码执行流程

    Java 代码执行流程 类加载过程 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载 类加载时机:代码使用到这个类时 验证阶段 &qu ...

  4. Java 获取一个字符串中,另一个字符串出现的次数

    Java 获取一个字符串中,另一个字符串出现的次数 思想: 1. indexOf到字符串中到第一次出现的索引2. 找到的索引+被找字符串长度,截取字符串3. 计数器++ 代码实现: public cl ...

  5. Java如何将字符串中的敏感词替换为相等数量的星号*

    Java如何将字符串中的敏感词替换为相等数量的星号* Java如何将字符串中的敏感词替换为相等数量的星号*,这也是我工作中遇到的问题,尝试了很多种方式最后采用这一种,在这里分享一下我的解决方式,代码效 ...

  6. Java-Runoob-高级教程-实例-字符串:03. Java 实例 - 删除字符串中的一个字符

    ylbtech-Java-Runoob-高级教程-实例-字符串:03. Java 实例 - 删除字符串中的一个字符 1.返回顶部 1. Java 实例 - 删除字符串中的一个字符  Java 实例 以 ...

  7. Java List转换为字符串的几种方法

    Java List转换为字符串的几种方法 import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import ...

  8. String:(字符串)中常用的方法

    package stringyiwen; //字符串中常用的方法public class StringTest03 { public static void main(String[] args) { ...

  9. Java:判断字符串中包含某字符的个数

    Java:判断字符串中包含某字符的个数 JAVA中查询一个词在内容中出现的次数: public int getCount(String str,String key){ if(str == null ...

随机推荐

  1. Ubuntu16.04基于Anaconda(py3.6)安装TensorFlow(CPU)的方法

    安装tensorflow(cpu版) 对anaconda命令的熟悉,可以参考http://www.jianshu.com/p/d2e15200ee9b 官方的建议是即时你有gpu,但也可以先装一个cp ...

  2. AngularJS转换请求内容

    在"AngularJS中转换响应内容"中,体验了如何转换响应内容.本篇来体验如何转换请求内容. 主页面通过onSend方法把request对象转递出去. <form name ...

  3. iOS:百度长语音识别具体的封装:识别、播放、进度刷新

    一.介绍 以前做过讯飞语音识别,比较简单,识别率很不错,但是它的识别时间是有限制的,最多60秒.可是有的时候我们需要更长的识别时间,例如朗诵古诗等功能.当然讯飞语音也是可以通过曲线救国来实现,就是每达 ...

  4. Unity Alpha融合参数(便查)

    Alpha Blending,中文译作Alpha混合 Blending就是控制透明的.处于光栅化的最后阶段. 这里例如我们给一个模型贴一个材质,那么在某个点计算出来颜色值称为源,而该点之前累积的颜色值 ...

  5. 使用JDBC在MySQL数据库中快速批量插入数据

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢? 在JDBC编程接口中Statement 有两个方法特别值得注意: void addBatch ...

  6. windows和linux文件输 - ftp

    1. linux到linux的复制直接用scp命令 但是windows下就麻烦点, 安装winscp, 配置用户名和密码即可随意拖拽了. 下载地址: 需要linux电脑的用户名和密码即可 2. win ...

  7. 利用Xmanager Enterprise 5的passive显示远程linux主机图形化信息

    问题描述: 最初的需求是,安装oracle数据(第一次安装都是图形化linxu进去一步步操作,后续发现可以命令静默安装不调用图形化,学习就是步步入深,方得始终),最初实现window弹出linux主机 ...

  8. PCA实现

    代码实现分成好多种层级,有的代码只使用标准库实现,有的代码基于其它库实现,有的代码直接调用库中现有的实现. 在本文中,按照不同的层级分别实现PCA 对于分类问题基本任务可以描述如下 x11 x12 x ...

  9. CorelCAD for Mac(绘图设计软件)破解版安装

    1.软件简介    CorelCAD 是 macOS 系统上的 CAD 绘图工具,为我们提供了获取本地 DWG 格式的高性能 CAD 设计解决方案.打开.处理和保存 .DWG 文件,实现轻松协作.借助 ...

  10. 解决ScrollView嵌套RecyclerView出现item显示不全的问题

      问题:ScrollView嵌套RecyclerView时,RecyclerView的item显示不全 出现问题不要慌,耐心解决才是王道,哈哈.首先说下出现这个问题的情景吧,首先声明这个问题在23版 ...