java怎么计算一个String类型的数学java 表达式计算引擎

java字符串应用之表达式解析器 - 菜菜 - ITeye博客
博客分类:
一、表达式的组成
2、运算符:+ - / * ^ % =
4、变量二、运算符优先级
由高到低分别为:+-(正负号)、^、*/%、+-、=
优先级相等的运算符按照从左到右的顺序计算三、关键技术点
1、确定运算的优先级,从高到低分别为:原子元素表达式,包括数字和变量;括号表达式;一元表达式,取数的负数;指数表达式;乘、除、取模表达式;加、减表达式;赋值表达式。
2、对于每一级别的运算,都由一个方法实现,在方法中先完成比自己高一级别的运算,再处理本级别的运算。因此,在计算整个表达式的主方法中,只需要调用最低级别的运算的实现方法即可。
3、确定表达式中的分隔符,(+、-、*、/、%、^、=、(、)、)。利用这些分隔符将表达式分成多段,每一段叫做一个token,分隔符也算token。
4、用长度为26的int数组vars存储变量的值。
5、Character的isWhitespace方法判断字符是否为空白符,用于去掉表达式中的空白符。
6、Character的isLetter方法判断字符是否为字母,用于提取表达式中的变量
7、Character的isDigit方法判断字符是否为数字,用于获取表达式中的数字
四、演示实例
/** *//** * 文件名ExpressionParser.java */package book.oo.S
/** *//** * 表达式解析器 * @author joe * */public class ExpressionParser ...{
//4种标记类型
public static final int NONE_TOKEN = 0;
//标记为空或者结束符
public static final int DELIMITER_TOKEN = 1;
//标记为分隔符
public static final int VARIABLE_TOKEN = 2;
//标记为变量
public static final int NUMBER_TOKEN = 3;
//标记为数字
//4种错误类型
public static final int SYNTAX_ERROR = 0;
//语法错误
public static final int UNBALPARENS_ERROR = 1;
//括号没有结束错误
public static final int NOEXP_ERROR = 2;
//表达式为空错误
public static final int DIVBYZERO_ERROR = 3;
//被0除错误
//针对4种错误类型定义的4个错误提示
public static final String[] ERROR_MESSAGES = ...{"Syntax Error", "Unbalanced " +
"Parentheses", "No Expression Present", "Division by Zero"};
//表达式的结束标记
public static final String EOE = ""/0";
private S //表达式字符串 private int expI //解析器当前指针在表达式中的位置 private S //解析器当前处理的标记 private int tokenT //解析器当前处理的标记类型 private double[] vars = new double[26]; //变量数组 /**
*/ public ExpressionParser() { }
* 解析一个表达式,返回表达式的值
*/ public double evaluate(String expStr) throws Exception {
this.exp = expS
this.expIndex = 0;
//获取第一个标记
this.getToken();
if (this.token.equals(EOE)) {
//没有表达式异常
this.handleError(NOEXP_ERROR);
result = this.parseAssign(); //处理赋值语句
//处理完赋值语句,应该就是表达式结束符,如果不是,则返回异常
if(!this.token.equals(EOE)) {
this.handleError(SYNTAX_ERROR);
* 处理赋值语句
*/ public double parseAssign() throws Exception { //结果
int varI //变量下标
String oldT //旧标记
int oldTokenT //旧标记的类型
//如果标记类型是变量
if (this.tokenType == VARIABLE_TOKEN) {
//保存当前标记
oldToken = new String(this.token);
oldTokenType = this.tokenT
//取得变量的索引,本解析器只支持一个字母的变量
//如果用户的变量字母长度大于1,则取第一个字母当作变量
varIndex = Character.toUpperCase(this.token.charAt(0)) - ''A'';
//获得下一个标记
this.getToken();
//如果当前标记不是等号=
if(!this.token.equals("=")) {
this.putBack(); //回滚
//不是一个赋值语句,将标记恢复到上一个标记
this.token = new String(oldToken);
this.tokenType = oldTokenT
//如果当前标记是等号=,即给变量赋值,形式如:a = 3 + 5;
//则计算等号后面表达式的值,然后再将得到的值赋给变量
this.getToken();
//因为加减法的优先级最低,所以计算加减法表达式
result = this.parseAddOrSub();
//将表达式的值赋给变量,并存在实例变量vars中
this.vars[varIndex] =
//如果当前标记类型不是变量,或者不是赋值语句,则用加减法计算表达式的值
return this.parseAddOrSub(); }
/** 计算加减法表达式 */ private double parseAddOrSub() throws Exception { //运算符 //结果
double partialR //子表达式的结果
result = this.pareseMulOrDiv(); //用乘除法计算当前表达式的值
//如果当前标记的第一个字母是加减号,则继续进行加减运算
while ((op = this.token.charAt(0)) == ''+'' || op == ''-'') {
this.getToken(); //取下一个标记
//用乘除法计算当前子表达式的值
partialResult = this.pareseMulOrDiv();
switch(op) {
case ''-'':
//如果是减法,则用已处理的子表达式的值减去当前子表达式的值
result = result - partialR
case ''+'':
//如果是加法,用已处理的子表达式的值加上当前子表达式的值
result = result + partialR
* 计算乘除法表达式,包括取模运算
*/ private double pareseMulOrDiv() throws Exception { //运算符 //结果
double partialR //子表达式结果
//用指数运算计算当前子表达式的值
result = this.parseExponent();
//如果当前标记的第一个字母是乘、除或者取模运算,则继续进行乘除法运算
while ((op = this.token.charAt(0)) == ''*'' || op == ''/'' || op == ''%'') {
this.getToken(); //取下一标记
//用指数运算计算当前子表达式的值
partialResult = this.parseExponent();
switch (op) {
case ''*'':
//如果是乘法,则用已处理子表达式的值乘以当前子表达式的值
result = result * partialR
case ''/'':
//如果是除法,判断当前字表达式的值是否为0,如果为0,则抛出被0除异常
if(partialResult == 0.0) {
this.handleError(DIVBYZERO_ERROR);
//除数不为0,则进行除法运算
result = result / partialR
case ''%'':
//如果是取模运算,也要判断当前子表达式的值是否为0
if(partialResult == 0.0) {
this.handleError(DIVBYZERO_ERROR);
result = result % partialR
* 计算指数表达式
*/ private double parseExponent() throws Exception { //结果
double partialR //子表达式的值 //指数的底数 //指数的幂
//用一元运算计算当前子表达式的值(底数)
result = this.parseUnaryOperator();
//如果当前标记为“^”,则为指数运算
if (this.token.equals("^")) {
//获取下一标记,即获得指数的幂
this.getToken();
partialResult = this.parseExponent();
if(partialResult == 0.0) {
//如果指数的幂为0,则指数的值为1
result = 1.0;
//否则,指数的值为个数为指数幂的底数相乘的结果
for (t = (int) partialResult - 1; t & 0; t--) {
result =result *
* 计算一元运算,+,-,表示正数和负数
*/ private double parseUnaryOperator() throws Exception{ //结果
S //运算符
//如果当前标记类型为分隔符,而且分隔符的值等于+或者-
if((this.tokenType == DELIMITER_TOKEN) && this.token.equals("+") || this.token.equals("-")) {
op = this.
this.getToken();
//用括号运算计算当前子表达式的值
result = this.parseBracket();
if(op.equals("-")) {
//如果运算符为-,则表示负数,将子表达式的值变为负数
result = -
* 计算括号运算
*/ private double parseBracket() throws Exception { //结果
//如果当前标记为左括号,则表示是一个括号运算
if (this.token.equals("(")) {
this.getToken(); //取下一标记
result = this.parseAddOrSub(); //用加减法运算计算子表达式的值
//如果当前标记不等于右括号,抛出括号不匹配异常
if (!this.token.equals(")")) {
this.handleError(UNBALPARENS_ERROR);
this.getToken(); //否则取下一个标记
//如果不是左括号,表示不是一个括号运算,则用原子元素运算计算子表达式值
result = this.parseAtomElement();
* 计算原子元素运算,包括变量和数字
*/ private double parseAtomElement() throws Exception {
double result = 0.0; //结果
switch(this.tokenType) {
case NUMBER_TOKEN:
//如果当前标记类型为数字
//将数字的字符串转换成数字值
result = Double.parseDouble(this.token);
} catch (NumberFormatException exc) {
this.handleError(SYNTAX_ERROR);
this.getToken(); //取下一个标记
case VARIABLE_TOKEN:
//如果当前标记类型是变量,则取变量的值
result = this.findVar(token);
this.getToken();
this.handleError(SYNTAX_ERROR);
* 根据变量名获取变量的值,如果变量名长度大于1,则只取变量的第一个字符
*/ private double findVar(String vname) throws Exception {
if (!Character.isLetter(vname.charAt(0))) {
this.handleError(SYNTAX_ERROR);
return 0.0;
//从实例变量数组vars中取出该变量的值
return vars[Character.toUpperCase(vname.charAt(0)) - ''A'']; }
* 回滚,将解析器当前指针往前移到当前标记位置
*/ private void putBack() {
if (this.token == EOE) {
//解析器当前指针往前移动
for (int i = 0; i & this.token.length(); i++ ){
this.expIndex--;
* 处理异常情况
*/ private void handleError(int errorType) throws Exception {
//遇到异常情况时,根据错误类型,取得异常提示信息,将提示信息封装在异常中抛出
throw new Exception(ERROR_MESSAGES[errorType]); }
* 获取下一个标记
*/ private void getToken() {
//设置初始值
this.token = "";
this.tokenType = NONE_TOKEN;
//检查表达式是否结束,如果解析器当前指针已经到达了字符串长度,
//则表明表达式已经结束,置当前标记的值为EOE
if(this.expIndex == this.exp.length()) {
this.token = EOE;
//跳过表达式中的空白符
while (this.expIndex & this.exp.length()
&& Character.isWhitespace(this.exp.charAt(this.expIndex))) {
++this.expI
//再次检查表达式是否结束
if (this.expIndex == this.exp.length()) {
this.token = EOE;
//取得解析器当前指针指向的字符
char currentChar = this.exp.charAt(this.expIndex);
//如果当前字符是一个分隔符,则认为这是一个分隔符标记
//给当前标记和标记类型赋值,并将指针后移
if(isDelim(currentChar)) {
this.token += currentC
this.expIndex++;
this.tokenType = DELIMITER_TOKEN;
} else if (Character.isLetter(currentChar)) {
//如果当前字符是一个字母,则认为是一个变量标记
//将解析器指针往后移,知道遇到一个分隔符,之间的字符都是变量的组成部分
while(!isDelim(currentChar)) {
this.token += currentC
this.expIndex++;
if(this.expIndex &= this.exp.length()) {
currentChar = this.exp.charAt(this.expIndex);
this.tokenType = VARIABLE_TOKEN; //设置标记类型为变量
} else if (Character.isDigit(currentChar)) {
//如果当前字符是一个数字,则认为当前标记的类型为数字
//将解析器指针后移,知道遇到一个分隔符,之间的字符都是该数字的组成部分
while(!isDelim(currentChar)) {
this.token += currentC
this.expIndex++;
if (this.expIndex &= this.exp.length()) {
currentChar = this.exp.charAt(this.expIndex);
this.tokenType = NUMBER_TOKEN; //设置标记类型为数字
//无法识别的字符,则认为表达式结束
this.token = EOE;
* 判断一个字符是否为分隔符
* 表达式中的字符包括:
* 加“+”、减“-”、乘“*”、除“/”、取模“%”、指数“^”、赋值“=”、左括号“(”、右括号“)”
*/ private boolean isDelim(char c) {
if (("+-*/%^=()".indexOf(c) != -1)) } /**
* @param args
*/ public static void main(String[] args) throws Exception{
ExpressionParser test = new ExpressionParser();
String exp1 = "a = 5.0";
System.out.println("exp1(/"a = 5.0/") = " + test.evaluate(exp1));
String exp2 = "b = 3.0";
System.out.println("exp2(/"b = 3.0/") = " + test.evaluate(exp2));
String exp3 = "(a + b) * (a - b)";
System.out.println("exp3(/"(a + b) * (a - b)/") = " + test.evaluate(exp3));
String exp4 = "3*5-4/2";
System.out.println("exp4(/"3*5-4/2/") = " + test.evaluate(exp4));
String exp5 = "(4-2) * ((a + b) / (a - b))";
System.out.println("exp5(/"(4 - 2) * ((a + b) / (a - b))/") = " + test.evaluate(exp5));
String exp6 = "5 % 2";
System.out.println("exp6(/"5 % 2/") = " + test.evaluate(exp6));
String exp7 = "3^2 * 5 + 4";
System.out.println("exp7(/"3^2 * 5 + 4/") = " + test.evaluate(exp7)); }}
输出结果:
exp1("a = 5.0") = 5.0exp2("b = 3.0") = 3.0exp3("(a + b) * (a - b)") = 16.0exp4("3*5-4/2") = 13.0exp5("(4 - 2) * ((a + b) / (a - b))") = 8.0exp6("5 % 2") = 1.0exp7("3^2 * 5 + 4") = 49.0
五、实例分析
表达式的解析,实际就是一个表达式的分解过程。根据分隔符将表达式分成若干段。然后计算每一段的值,最后都会归结到一个原子表达式。
浏览: 98371 次
来自: 重庆
要是保存到数据库,是怎么做呢,数据流这块,不太懂。。(*^__ ...
学习 最近正在看相关的文档 标记下
怎么下载不了??????
你把这个放到jdk的bin目录下就可以了
不知道能不能看懂哦。2011年4月 Java大版内专家分月排行榜第二2010年8月 Java大版内专家分月排行榜第二2010年5月 Java大版内专家分月排行榜第二2008年2月 Java大版内专家分月排行榜第二2007年7月 Java大版内专家分月排行榜第二
2011年2月 Java大版内专家分月排行榜第三2010年9月 Java大版内专家分月排行榜第三2008年9月 Java大版内专家分月排行榜第三2008年1月 Java大版内专家分月排行榜第三2007年11月 Java大版内专家分月排行榜第三2007年9月 Java大版内专家分月排行榜第三
2007年4月 Java大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。String类型数学表达式直接进行运算
String类型数学表达式直接进行运算
编辑:www.fx114.net
本篇文章主要介绍了"String类型数学表达式直接进行运算",主要涉及到String类型数学表达式直接进行运算方面的内容,对于String类型数学表达式直接进行运算感兴趣的同学可以参考一下。
今天遇到了一个需要将数据库中保存的表达式,替换其中的字符,并计算出值,java是不能直接计算的例如:&
Java代码&&
double&d&=&(3+5-(2-4)*2)/24;没有问题&&
但是:遇到&&&&(3+5-(2-4)*2)/24&&字符串的格式,就不能使用了&&
java是无法解决,但是javaScript中有一个eval函数是可以执行的,所以,可以通过其他途径执行javaScript就可以做到,而ScriptEngine是java的一个javaScript实现类,所以就找到了方法,详细方法见下&
Java代码&&
public&class&MapJ&{&&
&&&&private&String&//替换的编号&&
&&&&private&String&//值&&
&&&&public&String&getKey()&{&&
&&&&&&&&return&&&
&&&&public&void&setKey(String&key)&{&&
&&&&&&&&this.key&=&&&
&&&&public&String&getValue()&{&&
&&&&&&&&return&&&
&&&&public&void&setValue(String&value)&{&&
&&&&&&&&this.value&=&&&
&&&&public&MapJ(String&key,&String&value)&{&&
&&&&&&&&super();&&
&&&&&&&&this.key&=&&&
&&&&&&&&this.value&=&&&
&&&&public&MapJ()&{&&
&&&&&&&&super();&&
//实现类&&
import&java.util.L&&
import&javax.script.ScriptE&&
import&javax.script.ScriptEngineM&&
import&javax.script.ScriptE&&
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&&&
&&&&&&&&}&&
&&&&&&&&return&d;&&
import&java.util.ArrayL&&
import&java.util.L&&
public&class&JavaScriptTest&{&&
&&&&&*&@param&args&
&&&&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+&%&);&&
&&&&&&&&}&&
通过以上的方法即可实现此方法。
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:Java数学表达式计算(Expression Evaluator)
我的图书馆
Java数学表达式计算(Expression Evaluator)
常见的表达式计算lib有:&(1)parsii&Java代码&&String&exp&=&"2&+&(7-5)&*&3.14159&*&x&+&sin(0)";&&&&&&Scope&scope&=&Scope.create();&&Expression&parsiiExpr&=&Parser.parse(exp);&&Variable&var&=&scope.getVariable("x");&&var.setValue(X_VALUE);&&&&&&double&result&=&parsiiExpr.evaluate();&&&&System.out.println(result);&&(2)JEval&Java代码&&String&exp&=&"2&+&(7-5)&*&3.14159&*&#{x}&+&sin(0)";&&&&&&Evaluator&jevalEvaluator&=&new&Evaluator();&&jevalEvaluator.setVariables(Collections.singletonMap("x",&Double.toString(X_VALUE)));&&&&&&double&result&=&Double.parseDouble(jevalEvaluator.evaluate(exp));&&&&System.out.println(result);&&(3)JEPLite&Java代码&&String&exp&=&"2&+&(7-5)&*&3.14159&*&x&+&sin(0)";&&&&&&JEP&jep&=&new&JEP();&&jep.addVariable("x",&X_VALUE);&&jep.parseExpression(exp);&&DoubleStack&jepStack&=&new&DoubleStack();&&&&&&double&result&=&jep.getValue(jepStack);&&&&System.out.println(result);&&&&(157.5 KB)下载次数: 6
TA的最新馆藏
喜欢该文的人也喜欢如何编写一个高效的Java表达式求值程序 - ImportNew
当然,这个标题是有一点夺人眼球,但我确实这么做了(关于是否相信基准测试结果,这是另一个话题)。
所以,上周我一直在找一个小型、实用的计算数学表达式的类库。偶然间我在stackoverflow上看到了,里面推荐的库()确实是很快而且基本拥有我需要的所有特性。但不幸的是,它不支持提供限制变量范围(在虚拟机里面,所有变量都位于一个全局命名空间)。
所以,我做了一件正常人不会做的事情:重新发明轮子,自己编写一个解析器和执行器。那是一个下雨的周六,我想到了用一个小型递归向下的解析器,一个简化了的、可以计算表达式的抽象语法树。抽象语法树使用一个小型变量管理助手,看起来也没什么大不了的。但它不是没有用。我做出一个初步的实现并且执行速度特别快。在进行了一些测试后,更让我充满信心,它执行的所有运算都正确无误。我想与最前面提到的类库相比,确认这个计算器到底有多快。在没有对每个内部循环和其他的执行进行优化前,我不报太大的期望,毕竟有不少类库是商业软件。所以当我看到测试结果的时候很惊讶。下面的清单展示了一个小的基准测试,使用不同的类库计算同一个表达式。 parsii 是我编写的库,测试时用的是最终版本。这个版本做了一些简化,比如预先计算了常量表达式。但是没有使用任何“黑魔法”,比如生成字节码或者其他类似的操作。
在性能评估中,一个用例是执行表达式”2 + (7 – 5) * 3.14159 * x^(12-10) + sin(-3.141)”。其中的取值范围为0到1000000。测试时先运行10次,对JIT进行预热。然后再运行15次计算平均时间:
PARSII: 28.3 ms
现在我敢肯定,每一个类库都有自己的优势,所以不能直接对它们进行比较。尽管如此,令人吃惊的是一个简单实现的程序可以拥有这么好的表现。
如果读者对于编译器的原理不太了解的话,下面是一个关于编译器运行机制的简单介绍:
同其他的解析器或者编译器一样,parsii使用了传统的。它将字符流转化成词法单元流,所以”4 + 38″,也就是字符数组*, ‘ ‘,
‘+’, ‘ ‘, * , ‘ ‘, ‘‘, *被转化成:
+ (符号)
* (符号)
分词器取到一个字符,接着判断是一个什么类型的词法单元,然后再读入这个属于词法单元的所有字符。每一个词法单元都有类型、文本内容并且知道起始位置(行号和字符)。网上有很多深入的教程,所以在这里就不详细讲解了。你可以看一下源代码,但正如我说的,它只是一个初步的实现。
用来将传入的词法单元流翻译成可以执行的AST(抽象语法树),它是一个传统的自上而下递归解析器。这是实现解析器最简单的方式,完全手写,没有利用工具生成。像这样的解析器只拥有一个包含所有语法规则的方法。
同样,关于这种类型的解析器也有很多的教程,但是如何恰当地处理错误却缺少相关的示例。除了解析表达式的速度和正确性外,优秀的错误处理机制是一个优秀解析器的最核心因素之一。正如在源代码里看到的那样,实现起来并不是太困难。因为解析器在解析表达式的过程中从来不会抛出异常,
所有的错误都被收集起来,并且继续尽可能进行解析。即使在第一个错误发生以后已经不能成功解析生成AST,重要的是要能够尽可能的继续解析。因为在一次的执行中我们需要报告尽可能多的错误。这样的方法也同样用在了分词器报告上。比如报告非法格式的词法单元,例如带有2个小数点的浮点数,放到同样的错误列表中。
执行一个解析完成后的抽象语法树非常简单。每一个抽象语法树节点都包含一个计算方法,从根节点开始到父节点会调用这个它。这里的执行结果就是表达式的结果,一个简单的例子就是,包含了+、-、*等操作。
执行一个解析完成后的抽象语法树非常简单。每一个抽象语法树节点都包含一个计算方法,它的父亲从根节点开始调用此方法。算数运算,代表了+、-、*等操作。
为了减少执行时间,程序里运用了3种优化措施:首先,在完成解析AST后,在根节点上进行一个简化的方法调用,并且会扩散到每一个子节点。每一个节点判断自己的子表达式中是否有简化的表达形式。例如:对于,我们检查2个操作数是不是都是常量(数字)。如果是数字,我们将计算表达式并且返回一个包含计算结果的常量。对于函数,如果所有的参数都是常量的话,也会进行此类优化。
在表达式中使用变量时会执行第二种优化。这里使用map用来在需要的时候来对变量的值进行读写。这肯定是有效的,并且会进行很多次的查找。所以我们有一个叫做类,它包含了变量名称和变量值。在进行表达式解析时,变量在作用域范围内(仅是一个map)只被一次,之后就可以一直使用。由于每次查找都返回相同的实例,所以在计算表达式值时变量的访问就像读写字段一样廉价,因为我们刚刚获取了Variable类的。
第三个也是最后一个优化很可能不是经常起作用。但是由于易于实现,还是应用了这种尤华。它的功能基本上和名字“延迟运算”一样,主要用于函数调用。函数不会自动计算所有参数值,并且调用函数。而“延迟运算”会检查所有的参数,自行决定哪些参数需要计算。在中可以看到它应用的实例。
parsii遵循MIT许可证授权。在上可以找到所有的源代码,并且包含了预编译的jar包。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
可能感兴趣的文章
可以,转载请注明出处。
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNew

我要回帖

更多关于 java 动态表达式计算 的文章

 

随机推荐