mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
fix bug
This commit is contained in:
parent
d775ce9cca
commit
80f85390e4
@ -3,7 +3,7 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.4.4 (2020-09-23)
|
||||
# 5.4.4 (2020-09-28)
|
||||
|
||||
### 新特性
|
||||
* 【core 】 ServiceLoaderUtil改为使用contextClassLoader(pr#183@Gitee)
|
||||
@ -36,6 +36,7 @@
|
||||
* 【core 】 修复新建默认TreeSet没有默认比较器导致的问题(issue#1101@Github)
|
||||
* 【core 】 修复Linux下使用Windows路径分隔符导致的解压错误(issue#I1MW0E@Gitee)
|
||||
* 【core 】 修复Word07Writer写出map问题(issue#I1W49R@Gitee)
|
||||
* 【script 】 修复函数库脚本执行问题
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -44,13 +44,13 @@ public class NumberUtil {
|
||||
private static final int DEFAUT_DIV_SCALE = 10;
|
||||
|
||||
/**
|
||||
* 0-20对应的阶乘,超过20的阶乘会超过Long.MAX_VALUE
|
||||
*/
|
||||
private static final long[] FACTORIALS = new long[]{
|
||||
1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L, 6227020800L,
|
||||
87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L,
|
||||
2432902008176640000L};
|
||||
|
||||
* 0-20对应的阶乘,超过20的阶乘会超过Long.MAX_VALUE
|
||||
*/
|
||||
private static final long[] FACTORIALS = new long[]{
|
||||
1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L, 6227020800L,
|
||||
87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L,
|
||||
2432902008176640000L};
|
||||
|
||||
/**
|
||||
* 提供精确的加法运算
|
||||
*
|
||||
@ -448,7 +448,7 @@ public class NumberUtil {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
BigDecimal result =new BigDecimal(values[0]);
|
||||
BigDecimal result = new BigDecimal(values[0]);
|
||||
for (int i = 1; i < values.length; i++) {
|
||||
result = result.multiply(new BigDecimal(values[i]));
|
||||
}
|
||||
@ -756,13 +756,13 @@ public class NumberUtil {
|
||||
/**
|
||||
* 补充Math.ceilDiv() JDK8中添加了和Math.floorDiv()但却没有ceilDiv()
|
||||
*
|
||||
* @param v1 被除数
|
||||
* @param v2 除数
|
||||
* @param v1 被除数
|
||||
* @param v2 除数
|
||||
* @return 两个参数的商
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public static int ceilDiv(int v1, int v2) {
|
||||
return (int)Math.ceil((double)v1 / v2);
|
||||
return (int) Math.ceil((double) v1 / v2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------- round
|
||||
@ -1430,50 +1430,49 @@ public class NumberUtil {
|
||||
* @return 结果
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public static long factorial(long start, long end) {
|
||||
// 负数没有阶乘
|
||||
if(start < 0 || end < 0) {
|
||||
throw new IllegalArgumentException(String.format("Factorial start and end both must be >= 0, " +
|
||||
"but got start=%d, end=%d", start, end));
|
||||
}
|
||||
if (0L == start || start == end) {
|
||||
return 1L;
|
||||
}
|
||||
if (start < end) {
|
||||
return 0L;
|
||||
}
|
||||
return factorialMultiplyAndCheck(start, factorial(start - 1, end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算范围阶乘中校验中间的计算是否存在溢出,factorial提前做了负数和0的校验,因此这里没有校验数字的正负
|
||||
* @param a 乘数
|
||||
* @param b 被乘数
|
||||
* @return 如果 a * b的结果没有溢出直接返回,否则抛出异常
|
||||
*/
|
||||
private static long factorialMultiplyAndCheck(long a, long b) {
|
||||
if (a <= Long.MAX_VALUE / b) {
|
||||
return a * b;
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("Overflow in multiplication: {%d} * {%d}", a, b));
|
||||
}
|
||||
public static long factorial(long start, long end) {
|
||||
// 负数没有阶乘
|
||||
if (start < 0 || end < 0) {
|
||||
throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be >= 0, but got start={}, end={}", start, end));
|
||||
}
|
||||
if (0L == start || start == end) {
|
||||
return 1L;
|
||||
}
|
||||
if (start < end) {
|
||||
return 0L;
|
||||
}
|
||||
return factorialMultiplyAndCheck(start, factorial(start - 1, end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算阶乘
|
||||
* <p>
|
||||
* n! = n * (n-1) * ... * 2 * 1
|
||||
* </p>
|
||||
*
|
||||
* @param n 阶乘起始
|
||||
* @return 结果
|
||||
*/
|
||||
public static long factorial(long n) {
|
||||
if (n < 0 || n > 20) {
|
||||
throw new IllegalArgumentException(String.format("Factorial must have n >= 0 and n <= 20 for n!, " +
|
||||
"but got n = %d", n));
|
||||
}
|
||||
return FACTORIALS[(int) n];
|
||||
}
|
||||
/**
|
||||
* 计算范围阶乘中校验中间的计算是否存在溢出,factorial提前做了负数和0的校验,因此这里没有校验数字的正负
|
||||
*
|
||||
* @param a 乘数
|
||||
* @param b 被乘数
|
||||
* @return 如果 a * b的结果没有溢出直接返回,否则抛出异常
|
||||
*/
|
||||
private static long factorialMultiplyAndCheck(long a, long b) {
|
||||
if (a <= Long.MAX_VALUE / b) {
|
||||
return a * b;
|
||||
}
|
||||
throw new IllegalArgumentException(StrUtil.format("Overflow in multiplication: {} * {}", a, b));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算阶乘
|
||||
* <p>
|
||||
* n! = n * (n-1) * ... * 2 * 1
|
||||
* </p>
|
||||
*
|
||||
* @param n 阶乘起始
|
||||
* @return 结果
|
||||
*/
|
||||
public static long factorial(long n) {
|
||||
if (n < 0 || n > 20) {
|
||||
throw new IllegalArgumentException(StrUtil.format("Factorial must have n >= 0 and n <= 20 for n!, but got n = {}", n));
|
||||
}
|
||||
return FACTORIALS[(int) n];
|
||||
}
|
||||
|
||||
/**
|
||||
* 平方根算法<br>
|
||||
@ -1736,11 +1735,11 @@ public class NumberUtil {
|
||||
*/
|
||||
public static boolean equals(BigDecimal bigNum1, BigDecimal bigNum2) {
|
||||
//noinspection NumberEquality
|
||||
if (bigNum1 == bigNum2){
|
||||
if (bigNum1 == bigNum2) {
|
||||
// 如果用户传入同一对象,省略compareTo以提高性能。
|
||||
return true;
|
||||
}
|
||||
if (bigNum1==null || bigNum2==null){
|
||||
if (bigNum1 == null || bigNum2 == null) {
|
||||
return false;
|
||||
}
|
||||
return 0 == bigNum1.compareTo(bigNum2);
|
||||
@ -1838,7 +1837,7 @@ public class NumberUtil {
|
||||
*
|
||||
* @param numberArray 数字数组
|
||||
* @return 最小值
|
||||
* @see ArrayUtil#min(Comparable[])
|
||||
* @see ArrayUtil#min(Comparable[])
|
||||
* @since 5.0.8
|
||||
*/
|
||||
public static BigDecimal min(BigDecimal... numberArray) {
|
||||
@ -2186,17 +2185,17 @@ public class NumberUtil {
|
||||
public static BigDecimal pow(BigDecimal number, int n) {
|
||||
return number.pow(n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断一个整数是否是2的幂
|
||||
*
|
||||
* @param n 待验证的整数
|
||||
* @return 如果n是2的幂返回true, 反之返回false
|
||||
*/
|
||||
public static boolean isPowerOfTwo(long n) {
|
||||
return (n > 0) && ((n & (n - 1)) == 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断一个整数是否是2的幂
|
||||
*
|
||||
* @param n 待验证的整数
|
||||
* @return 如果n是2的幂返回true, 反之返回false
|
||||
*/
|
||||
public static boolean isPowerOfTwo(long n) {
|
||||
return (n > 0) && ((n & (n - 1)) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析转换数字字符串为int型数字,规则如下:
|
||||
|
@ -151,7 +151,12 @@ public class ScriptUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Javascript脚本,返回Invocable
|
||||
* 执行Javascript脚本,返回Invocable,此方法分为两种情况:
|
||||
*
|
||||
* <ol>
|
||||
* <li>执行的脚本返回值是可执行的脚本方法</li>
|
||||
* <li>脚本为函数库,则ScriptEngine本身为可执行方法</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param script 脚本内容
|
||||
* @return 执行结果
|
||||
@ -159,11 +164,23 @@ public class ScriptUtil {
|
||||
* @since 5.3.6
|
||||
*/
|
||||
public static Invocable evalInvocable(String script) throws ScriptRuntimeException {
|
||||
return (Invocable) eval(script);
|
||||
final ScriptEngine jsEngine = getJsEngine();
|
||||
final Object eval;
|
||||
try {
|
||||
eval = jsEngine.eval(script);
|
||||
} catch (ScriptException e) {
|
||||
throw new ScriptRuntimeException(e);
|
||||
}
|
||||
if(eval instanceof Invocable){
|
||||
return (Invocable)eval;
|
||||
} else if(jsEngine instanceof Invocable){
|
||||
return (Invocable)jsEngine;
|
||||
}
|
||||
throw new ScriptRuntimeException("Script is not invocable !");
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Javascript脚本
|
||||
* 执行有返回值的Javascript脚本
|
||||
*
|
||||
* @param script 脚本内容
|
||||
* @return 执行结果
|
||||
@ -179,7 +196,7 @@ public class ScriptUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行脚本
|
||||
* 执行有返回值的脚本
|
||||
*
|
||||
* @param script 脚本内容
|
||||
* @param context 脚本上下文
|
||||
@ -196,7 +213,7 @@ public class ScriptUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行脚本
|
||||
* 执行有返回值的脚本
|
||||
*
|
||||
* @param script 脚本内容
|
||||
* @param bindings 绑定的参数
|
||||
|
@ -0,0 +1,22 @@
|
||||
package cn.hutool.script.test;
|
||||
|
||||
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class NashornDeepTest {
|
||||
|
||||
public static void main(String[] args) throws ScriptException, NoSuchMethodException {
|
||||
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
|
||||
|
||||
engine.eval(ResourceUtil.readUtf8Str("filter1.js"));
|
||||
|
||||
final Object filter1 = ((Invocable) engine).invokeFunction("filter1", 1, 2);
|
||||
Assert.assertFalse((Boolean) filter1);
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package cn.hutool.script.test;
|
||||
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.script.ScriptRuntimeException;
|
||||
import cn.hutool.script.ScriptUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.script.CompiledScript;
|
||||
@ -31,6 +33,12 @@ public class ScriptUtilTest {
|
||||
ScriptUtil.eval("print('Script test!');");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeTest() {
|
||||
final Object result = ScriptUtil.invoke(ResourceUtil.readUtf8Str("filter1.js"), "filter1", 2, 1);
|
||||
Assert.assertTrue((Boolean) result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pythonTest() throws ScriptException {
|
||||
final ScriptEngine pythonEngine = ScriptUtil.getPythonEngine();
|
||||
|
6
hutool-script/src/test/resources/filter1.js
Normal file
6
hutool-script/src/test/resources/filter1.js
Normal file
@ -0,0 +1,6 @@
|
||||
function filter1(a, b) {
|
||||
if (a > b) {
|
||||
return a > b;
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user