diff --git a/pom.xml b/pom.xml
index 39a0400..8a1a2cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,12 +25,6 @@
${guava.version}
-
- org.apache.commons
- commons-lang3
- ${commons-lang3.version}
-
-
joda-time
joda-time
@@ -40,6 +34,13 @@
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+ test
+
+
ch.qos.logback
logback-classic
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/JRE.java b/src/main/java/xyz/zhouxy/plusone/commons/base/JRE.java
index a4ae6cf..fa0d3d4 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/base/JRE.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/base/JRE.java
@@ -17,8 +17,7 @@
package xyz.zhouxy.plusone.commons.base;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.reflect.MethodUtils;
+import xyz.zhouxy.plusone.commons.util.StringTools;
/**
* JRE version
@@ -35,23 +34,30 @@ public class JRE {
private static int getJre() {
String version = System.getProperty("java.version");
- boolean isBlank = StringUtils.isBlank(version);
- if (!isBlank && version.startsWith("1.8")) {
+ boolean isNotBlank = StringTools.isNotBlank(version);
+ if (isNotBlank && version.startsWith("1.8")) {
return JAVA_8;
}
// if JRE version is 9 or above, we can get version from
// java.lang.Runtime.version()
try {
- Object javaRunTimeVersion = MethodUtils.invokeMethod(Runtime.getRuntime(), "version");
- return (int) MethodUtils.invokeMethod(javaRunTimeVersion, "major");
+ return getMajorVersion(version);
} catch (Exception e) {
- // Can't determine current JRE version (maybe java.version is null),
// assuming that JRE version is 8.
}
// default java 8
return JAVA_8;
}
+ private static int getMajorVersion(String version) {
+ if (version.startsWith("1.")) {
+ return Integer.parseInt(version.substring(2, 3));
+ } else {
+ int dotIndex = version.indexOf(".");
+ return (dotIndex != -1) ? Integer.parseInt(version.substring(0, dotIndex)) : Integer.parseInt(version);
+ }
+ }
+
private JRE() {
throw new IllegalStateException("Utility class");
}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java
index 9db260a..2ad3374 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java
@@ -23,12 +23,11 @@ import java.util.stream.Collectors;
import javax.annotation.Nullable;
-import org.apache.commons.lang3.StringUtils;
-
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import xyz.zhouxy.plusone.commons.annotation.Virtual;
+import xyz.zhouxy.plusone.commons.util.StringTools;
/**
* 分页排序查询参数
@@ -57,7 +56,7 @@ public class PagingAndSortingQueryParams {
Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(),
"Sortable properties can not be empty.");
sortableProperties.forEach((k, v) ->
- Preconditions.checkArgument(StringUtils.isNotBlank(k) && StringUtils.isNotBlank(v),
+ Preconditions.checkArgument(StringTools.isNotBlank(k) && StringTools.isNotBlank(v),
"Property name must not be blank."));
this.sortableProperties = ImmutableMap.copyOf(sortableProperties);
}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/BigDecimals.java b/src/main/java/xyz/zhouxy/plusone/commons/util/BigDecimals.java
index f56a998..e502a77 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/BigDecimals.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/BigDecimals.java
@@ -1,11 +1,10 @@
package xyz.zhouxy.plusone.commons.util;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import javax.annotation.Nullable;
-import org.apache.commons.lang3.StringUtils;
-
import com.google.common.base.Preconditions;
public class BigDecimals {
@@ -37,7 +36,171 @@ public class BigDecimals {
}
public static BigDecimal of(final String val) {
- return (StringUtils.isBlank(val)) ? ZERO : new BigDecimal(val);
+ return (StringTools.isNotBlank(val)) ? new BigDecimal(val) : ZERO;
+ }
+
+ /**
+ * 默认除法运算精度
+ */
+ private static final int DEF_DIV_SCALE = 10;
+
+ /**
+ * 提供精确的加法运算。
+ *
+ * @param v1 被加数
+ * @param v2 加数
+ * @return 两个参数的和
+ */
+ public static double add(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.add(b2).doubleValue();
+ }
+
+ /**
+ * 提供精确的减法运算。
+ *
+ * @param v1 被减数
+ * @param v2 减数
+ * @return 两个参数的差
+ */
+ public static double subtract(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.subtract(b2).doubleValue();
+ }
+
+ /**
+ * 提供精确的乘法运算。
+ *
+ * @param v1 被乘数
+ * @param v2 乘数
+ * @return 两个参数的积
+ */
+ public static double multiply(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.multiply(b2).doubleValue();
+ }
+
+ /**
+ * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
+ * 小数点以后10位,以后的数字四舍五入。
+ *
+ * @param v1 被除数
+ * @param v2 除数
+ * @return 两个参数的商
+ */
+ public static double divide(double v1, double v2) {
+ return divide(v1, v2, DEF_DIV_SCALE);
+ }
+
+ /**
+ * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
+ * 定精度,以后的数字四舍五入。
+ *
+ * @param v1 被除数
+ * @param v2 除数
+ * @param scale 表示表示需要精确到小数点以后几位。
+ * @return 两个参数的商
+ */
+ public static double divide(double v1, double v2, int scale) {
+ if (scale < 0) {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.divide(b2, scale, RoundingMode.HALF_EVEN).doubleValue();
+ }
+
+ /**
+ * 提供精确的小数位四舍五入处理。
+ *
+ * @param v 需要四舍五入的数字
+ * @param scale 小数点后保留几位
+ * @return 四舍五入后的结果
+ */
+ public static double round(double v, int scale) {
+ if (scale < 0) {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b = BigDecimal.valueOf(v);
+ BigDecimal one = new BigDecimal("1");
+ return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ /**
+ * 提供精确的类型转换(Float)
+ *
+ * @param v 需要被转换的数字
+ * @return 返回转换结果
+ */
+ public static float convertToFloat(double v) {
+ BigDecimal b = BigDecimal.valueOf(v);
+ return b.floatValue();
+ }
+
+ /**
+ * 提供精确的类型转换(Int)不进行四舍五入
+ *
+ * @param v 需要被转换的数字
+ * @return 返回转换结果
+ */
+ public static int convertsToInt(double v) {
+ BigDecimal b = BigDecimal.valueOf(v);
+ return b.intValue();
+ }
+
+ /**
+ * 提供精确的类型转换(Long)
+ *
+ * @param v 需要被转换的数字
+ * @return 返回转换结果
+ */
+ public static long convertsToLong(double v) {
+ BigDecimal b = BigDecimal.valueOf(v);
+ return b.longValue();
+ }
+
+ /**
+ * 返回两个数中大的一个值
+ *
+ * @param v1 需要被对比的第一个数
+ * @param v2 需要被对比的第二个数
+ * @return 返回两个数中大的一个值
+ */
+ public static double returnMax(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.max(b2).doubleValue();
+ }
+
+ /**
+ * 返回两个数中小的一个值
+ *
+ * @param v1 需要被对比的第一个数
+ * @param v2 需要被对比的第二个数
+ * @return 返回两个数中小的一个值
+ */
+ public static double returnMin(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.min(b2).doubleValue();
+ }
+
+ /**
+ * 精确对比两个数字
+ *
+ * @param v1 需要被对比的第一个数
+ * @param v2 需要被对比的第二个数
+ * @return 如果两个数一样则返回0,如果第一个数比第二个数大则返回1,反之返回-1
+ */
+ public static int compareTo(double v1, double v2) {
+ BigDecimal b1 = BigDecimal.valueOf(v1);
+ BigDecimal b2 = BigDecimal.valueOf(v2);
+ return b1.compareTo(b2);
}
private BigDecimals() {
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/Enumeration.java b/src/main/java/xyz/zhouxy/plusone/commons/util/Enumeration.java
index d4ea36b..5357e9c 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/Enumeration.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/Enumeration.java
@@ -24,8 +24,6 @@ import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
-
import com.google.common.base.Preconditions;
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
@@ -45,7 +43,7 @@ public abstract class Enumeration> // NOSONAR 暂不移
protected final String name;
protected Enumeration(final int id, final String name) {
- Preconditions.checkArgument(StringUtils.isNotBlank(name), "Name of enumeration must has text.");
+ Preconditions.checkArgument(StringTools.isNotBlank(name), "Name of enumeration must has text.");
this.id = id;
this.name = name;
}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java
new file mode 100644
index 0000000..2016d83
--- /dev/null
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/StringTools.java
@@ -0,0 +1,20 @@
+package xyz.zhouxy.plusone.commons.util;
+
+public class StringTools {
+
+ public static boolean isNotBlank(final String cs) {
+ if (cs == null || cs.isEmpty()) {
+ return false;
+ }
+ for (int i = 0; i < cs.length(); i++) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private StringTools() {
+ throw new IllegalStateException("Utility class");
+ }
+}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
index 4ebab7f..9166e61 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
@@ -6,6 +6,7 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
@@ -47,15 +48,14 @@ class DateTimeToolsTests {
void testToJodaDateTime() {
ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault());
Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli());
-
+
org.joda.time.format.DateTimeFormatter f = org.joda.time.format.DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+08:00"));
log.info("jodaDateTime: {}", jodaDateTime);
assertEquals("2008-01-08 10:23:50.108", f.print(jodaDateTime));
-
-
+
jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+02:00"));
log.info("jodaDateTime: {}", jodaDateTime);
assertEquals("2008-01-08 04:23:50.108", f.print(jodaDateTime));
@@ -65,8 +65,8 @@ class DateTimeToolsTests {
void test() {
java.time.Instant now = java.time.Instant.now();
org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(now, ZoneId.of("America/New_York"));
- org.joda.time.format.DateTimeFormatter formatter =
- org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
+ org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat
+ .forPattern("yyyy-MM-dd HH:mm:ss.SSS");
log.info(formatter.print(jodaDateTime));
log.info(jodaDateTime.getZone().toString());
log.info(jodaDateTime.toString());
@@ -74,7 +74,8 @@ class DateTimeToolsTests {
org.joda.time.Instant instant = new org.joda.time.Instant(System.currentTimeMillis() - 500000);
log.info(instant.toString());
log.info(DateTimeTools.toJavaInstant(instant).toString());
- log.info(DateTimeTools.toZonedDateTime(instant, org.joda.time.DateTimeZone.forID("America/New_York")).toString());
+ log.info(DateTimeTools.toZonedDateTime(instant, org.joda.time.DateTimeZone.forID("America/New_York"))
+ .toString());
}
@Test
@@ -84,5 +85,10 @@ class DateTimeToolsTests {
org.joda.time.Instant jodaInstant = DateTimeTools.toJodaInstant(javaInstant);
log.info("jodaInstant: {}", jodaInstant);
+
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
+ DateTimeFormatter formatter2 = formatter.withZone(ZoneId.systemDefault());
+ log.info("{}", formatter);
+ log.info("{}", formatter2);
}
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java
index a1f56f6..197ca89 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java
@@ -1,7 +1,9 @@
package xyz.zhouxy.plusone.commons.util;
+import java.io.Serializable;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
@@ -10,6 +12,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
+import cn.hutool.core.util.ObjectUtil;
import lombok.ToString;
class TreeBuilderTests {
@@ -37,11 +40,15 @@ class TreeBuilderTests {
/**//**/MenuItem.of("C1", "C1002", "三级菜单C1002", "/c/c1/c1002", 2),
/**/MenuItem.of("C", "C2", "二级菜单C2", "/c/c2", 1));
- List