This commit is contained in:
Looly 2021-12-09 00:19:57 +08:00
parent b1433317fe
commit 95e8c812ef
4 changed files with 54 additions and 48 deletions

View File

@ -36,6 +36,7 @@
* 【db 】 Db增加query重载可支持自定义PreparedStatement从而支持游标issue#I4JXWN@Gitee
* 【cache 】 CacheObj增加getExpiredTime等方法issue#I4LE80@Gitee
* 【extra 】 Ftp增加backToPwd方法issue#2004@Github
* 【core 】 CollStreamUtil修改集合中null处理问题pr#478@Gitee
*
### 🐞Bug修复
* 【core 】 修复FileResource构造fileName参数无效问题issue#1942@Github

View File

@ -5,7 +5,14 @@ import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.stream.StreamUtil;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -48,8 +55,7 @@ public class CollStreamUtil {
if (CollUtil.isEmpty(collection)) {
return Collections.emptyMap();
}
return StreamUtil.of(collection, isParallel)
.collect(HashMap::new, (HashMap<K, V> m, V v) -> m.put(Opt.ofNullable(v).map(key).get(), v), HashMap::putAll);
return toMap(collection, (v)-> Opt.ofNullable(v).map(key).get(), Function.identity(), isParallel);
}
/**
@ -82,7 +88,8 @@ public class CollStreamUtil {
if (CollUtil.isEmpty(collection)) {
return Collections.emptyMap();
}
return StreamUtil.of(collection, isParallel).collect(HashMap::new, (HashMap<K, V> m, E v) -> m.put(key.apply(v), value.apply(v)), HashMap::putAll);
return StreamUtil.of(collection, isParallel)
.collect(HashMap::new, (m, v) -> m.put(key.apply(v), value.apply(v)), HashMap::putAll);
}

View File

@ -16,7 +16,6 @@ import java.util.Stack;
*/
public class Calculator {
private final Stack<String> postfixStack = new Stack<>();// 后缀式栈
private final Stack<Character> opStack = new Stack<>();// 运算符栈
private final int[] operatPriority = new int[]{0, 3, 2, 1, -1, 1, 0, 2};// 运用运算符ASCII码-40做索引的运算符优先级
/**
@ -26,39 +25,7 @@ public class Calculator {
* @return 计算结果
*/
public static double conversion(String expression) {
final Calculator cal = new Calculator();
expression = transform(expression);
return cal.calculate(expression);
}
/**
* 将表达式中负数的符号更改
*
* @param expression 例如-2+-1*(-3E-2)-(-1) 被转为 ~2+~1*(~3E~2)-(~1)
* @return 转换后的字符串
*/
private static String transform(String expression) {
expression = StrUtil.cleanBlank(expression);
expression = StrUtil.removeSuffix(expression, "=");
final char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '-') {
if (i == 0) {
arr[i] = '~';
} else {
char c = arr[i - 1];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
arr[i] = '~';
}
}
}
}
if (arr[0] == '~' || (arr.length > 1 && arr[1] == '(')) {
arr[0] = '-';
return "0" + new String(arr);
} else {
return new String(arr);
}
return (new Calculator()).calculate(expression);
}
/**
@ -68,15 +35,16 @@ public class Calculator {
* @return 计算结果
*/
public double calculate(String expression) {
prepare(transform(expression));
Stack<String> resultStack = new Stack<>();
prepare(expression);
Collections.reverse(postfixStack);// 将后缀式栈反转
String firstValue, secondValue, currentValue;// 参与计算的第一个值第二个值和算术运算符
String firstValue, secondValue, currentOp;// 参与计算的第一个值第二个值和算术运算符
while (false == postfixStack.isEmpty()) {
currentValue = postfixStack.pop();
if (false == isOperator(currentValue.charAt(0))) {// 如果不是运算符则存入操作数栈中
currentValue = currentValue.replace("~", "-");
resultStack.push(currentValue);
currentOp = postfixStack.pop();
if (false == isOperator(currentOp.charAt(0))) {// 如果不是运算符则存入操作数栈中
currentOp = currentOp.replace("~", "-");
resultStack.push(currentOp);
} else {// 如果是运算符则从操作数栈中取两个值和该数值一起参与运算
secondValue = resultStack.pop();
firstValue = resultStack.pop();
@ -85,7 +53,7 @@ public class Calculator {
firstValue = firstValue.replace("~", "-");
secondValue = secondValue.replace("~", "-");
BigDecimal tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
BigDecimal tempResult = calculate(firstValue, secondValue, currentOp.charAt(0));
resultStack.push(tempResult.toString());
}
}
@ -98,6 +66,7 @@ public class Calculator {
* @param expression 表达式
*/
private void prepare(String expression) {
final Stack<Character> opStack = new Stack<>();
opStack.push(',');// 运算符放入栈底元素逗号此符号优先级最低
char[] arr = expression.toCharArray();
int currentIndex = 0;// 当前字符的位置
@ -152,7 +121,7 @@ public class Calculator {
*
* @param cur 下标
* @param peek peek
* @return 优先级
* @return 优先级如果cur高或相等返回true否则false
*/
private boolean compare(char cur, char peek) {// 如果是peek优先级高于cur返回true默认都是peek优先级要低
final int offset = 40;
@ -199,4 +168,34 @@ public class Calculator {
}
return result;
}
/**
* 将表达式中负数的符号更改
*
* @param expression 例如-2+-1*(-3E-2)-(-1) 被转为 ~2+~1*(~3E~2)-(~1)
* @return 转换后的字符串
*/
private static String transform(String expression) {
expression = StrUtil.cleanBlank(expression);
expression = StrUtil.removeSuffix(expression, "=");
final char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '-') {
if (i == 0) {
arr[i] = '~';
} else {
char c = arr[i - 1];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
arr[i] = '~';
}
}
}
}
if (arr[0] == '~' || (arr.length > 1 && arr[1] == '(')) {
arr[0] = '-';
return "0" + new String(arr);
} else {
return new String(arr);
}
}
}

View File

@ -1,7 +1,6 @@
package cn.hutool.core.math;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
public class CalculatorTest {
@ -31,7 +30,7 @@ public class CalculatorTest {
}
@Test
@Ignore
// @Ignore
public void conversationTest5(){
// https://github.com/dromara/hutool/issues/1984
final double conversion = Calculator.conversion("((1/1) / (1/1) -1) * 100");