diff --git a/CHANGELOG.md b/CHANGELOG.md index 34bb35a0c..b26cbf06b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ * 【core 】 针对JDK8+的日期,统一归档到TimeUtil * 【core 】 CopyOptions参数重构 * 【db 】 增加DDL封装 -* 【json 】 删除JSONNull * 【json 】 实现自定义的类型转换,不影响全局的转换器 ### ❌不兼容特性 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java index 98a42240c..8021d3eab 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/NumberWordFormatter.java @@ -72,7 +72,7 @@ public class NumberWordFormatter { index++; } } - return String.format("%s%s", NumberUtil.decimalFormat("#.##", res), NUMBER_SUFFIX[index]); + return String.format("%s%s", NumberUtil.format("#.##", res), NUMBER_SUFFIX[index]); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java index 575f8a9e0..c8835ea89 100644 --- a/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/math/NumberUtil.java @@ -1,11 +1,9 @@ package cn.hutool.core.math; -import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.lang.Assert; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; -import cn.hutool.core.util.RandomUtil; import java.math.BigDecimal; import java.math.BigInteger; @@ -14,8 +12,6 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; /** * 数字工具类
@@ -55,75 +51,6 @@ public class NumberUtil { 87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L, 2432902008176640000L}; - /** - * 提供精确的加法运算 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - */ - public static double add(final float v1, final float v2) { - return add(Float.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的加法运算 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - */ - public static double add(final float v1, final double v2) { - return add(Float.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的加法运算 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - */ - public static double add(final double v1, final float v2) { - return add(Double.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的加法运算 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - */ - public static double add(final double v1, final double v2) { - return add(Double.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的加法运算 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - * @since 3.1.1 - */ - public static double add(final Double v1, final Double v2) { - //noinspection RedundantCast - return add((Number) v1, (Number) v2).doubleValue(); - } - - /** - * 提供精确的加法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param v1 被加数 - * @param v2 加数 - * @return 和 - */ - public static BigDecimal add(final Number v1, final Number v2) { - return add(new Number[]{v1, v2}); - } - /** * 提供精确的加法运算
* 如果传入多个值为null或者空,则返回0 @@ -172,98 +99,6 @@ public class NumberUtil { return result; } - /** - * 提供精确的加法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param values 多个被加值 - * @return 和 - * @since 4.0.0 - */ - public static BigDecimal add(final BigDecimal... values) { - if (ArrayUtil.isEmpty(values)) { - return BigDecimal.ZERO; - } - - BigDecimal value = values[0]; - BigDecimal result = toBigDecimal(value); - for (int i = 1; i < values.length; i++) { - value = values[i]; - if (null != value) { - result = result.add(value); - } - } - return result; - } - - /** - * 提供精确的减法运算 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static double sub(final float v1, final float v2) { - return sub(Float.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的减法运算 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static double sub(final float v1, final double v2) { - return sub(Float.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的减法运算 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static double sub(final double v1, final float v2) { - return sub(Double.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的减法运算 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static double sub(final double v1, final double v2) { - return sub(Double.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的减法运算 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static double sub(final Double v1, final Double v2) { - //noinspection RedundantCast - return sub((Number) v1, (Number) v2).doubleValue(); - } - - /** - * 提供精确的减法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param v1 被减数 - * @param v2 减数 - * @return 差 - */ - public static BigDecimal sub(final Number v1, final Number v2) { - return sub(new Number[]{v1, v2}); - } - /** * 提供精确的减法运算
* 如果传入多个值为null或者空,则返回0 @@ -312,99 +147,6 @@ public class NumberUtil { return result; } - /** - * 提供精确的减法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param values 多个被减值 - * @return 差 - * @since 4.0.0 - */ - public static BigDecimal sub(final BigDecimal... values) { - if (ArrayUtil.isEmpty(values)) { - return BigDecimal.ZERO; - } - - BigDecimal value = values[0]; - BigDecimal result = toBigDecimal(value); - for (int i = 1; i < values.length; i++) { - value = values[i]; - if (null != value) { - result = result.subtract(value); - } - } - return result; - } - - /** - * 提供精确的乘法运算 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static double mul(final float v1, final float v2) { - return mul(Float.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的乘法运算 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static double mul(final float v1, final double v2) { - return mul(Float.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的乘法运算 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static double mul(final double v1, final float v2) { - return mul(Double.toString(v1), Float.toString(v2)).doubleValue(); - } - - /** - * 提供精确的乘法运算 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static double mul(final double v1, final double v2) { - return mul(Double.toString(v1), Double.toString(v2)).doubleValue(); - } - - /** - * 提供精确的乘法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static double mul(final Double v1, final Double v2) { - //noinspection RedundantCast - return mul((Number) v1, (Number) v2).doubleValue(); - } - - /** - * 提供精确的乘法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - */ - public static BigDecimal mul(final Number v1, final Number v2) { - return mul(new Number[]{v1, v2}); - } - /** * 提供精确的乘法运算
* 如果传入多个值为null或者空,则返回0 @@ -427,18 +169,6 @@ public class NumberUtil { return result; } - /** - * 提供精确的乘法运算 - * - * @param v1 被乘数 - * @param v2 乘数 - * @return 积 - * @since 3.0.8 - */ - public static BigDecimal mul(final String v1, final String v2) { - return mul(new BigDecimal(v1), new BigDecimal(v2)); - } - /** * 提供精确的乘法运算
* 如果传入多个值为null或者空,则返回0 @@ -460,81 +190,6 @@ public class NumberUtil { return result; } - /** - * 提供精确的乘法运算
- * 如果传入多个值为null或者空,则返回0 - * - * @param values 多个被乘值 - * @return 积 - * @since 4.0.0 - */ - public static BigDecimal mul(final BigDecimal... values) { - if (ArrayUtil.isEmpty(values) || ArrayUtil.hasNull(values)) { - return BigDecimal.ZERO; - } - - BigDecimal result = values[0]; - for (int i = 1; i < values.length; i++) { - result = result.multiply(values[i]); - } - return result; - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @return 两个参数的商 - */ - public static double div(final float v1, final float v2) { - return div(v1, v2, DEFAULT_DIV_SCALE); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @return 两个参数的商 - */ - public static double div(final float v1, final double v2) { - return div(v1, v2, DEFAULT_DIV_SCALE); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @return 两个参数的商 - */ - public static double div(final double v1, final float v2) { - return div(v1, v2, DEFAULT_DIV_SCALE); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @return 两个参数的商 - */ - public static double div(final double v1, final double v2) { - return div(v1, v2, DEFAULT_DIV_SCALE); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @return 两个参数的商 - */ - public static double div(final Double v1, final Double v2) { - return div(v1, v2, DEFAULT_DIV_SCALE); - } - /** * 提供(相对)精确的除法运算,当发生除不尽的情况的时候,精确到小数点后10位,后面的四舍五入 * @@ -558,66 +213,6 @@ public class NumberUtil { return div(v1, v2, DEFAULT_DIV_SCALE); } - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @return 两个参数的商 - */ - public static double div(final float v1, final float v2, final int scale) { - return div(v1, v2, scale, RoundingMode.HALF_UP); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @return 两个参数的商 - */ - public static double div(final float v1, final double v2, final int scale) { - return div(v1, v2, scale, RoundingMode.HALF_UP); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @return 两个参数的商 - */ - public static double div(final double v1, final float v2, final int scale) { - return div(v1, v2, scale, RoundingMode.HALF_UP); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @return 两个参数的商 - */ - public static double div(final double v1, final double v2, final int scale) { - return div(v1, v2, scale, RoundingMode.HALF_UP); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @return 两个参数的商 - */ - public static double div(final Double v1, final Double v2, final int scale) { - return div(v1, v2, scale, RoundingMode.HALF_UP); - } - /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度,后面的四舍五入 * @@ -643,89 +238,6 @@ public class NumberUtil { return div(v1, v2, scale, RoundingMode.HALF_UP); } - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - */ - public static double div(final float v1, final float v2, final int scale, final RoundingMode roundingMode) { - return div(Float.toString(v1), Float.toString(v2), scale, roundingMode).doubleValue(); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - */ - public static double div(final float v1, final double v2, final int scale, final RoundingMode roundingMode) { - return div(Float.toString(v1), Double.toString(v2), scale, roundingMode).doubleValue(); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - */ - public static double div(final double v1, final float v2, final int scale, final RoundingMode roundingMode) { - return div(Double.toString(v1), Float.toString(v2), scale, roundingMode).doubleValue(); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - */ - public static double div(final double v1, final double v2, final int scale, final RoundingMode roundingMode) { - return div(Double.toString(v1), Double.toString(v2), scale, roundingMode).doubleValue(); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - */ - public static double div(final Double v1, final Double v2, final int scale, final RoundingMode roundingMode) { - //noinspection RedundantCast - return div((Number) v1, (Number) v2, scale, roundingMode).doubleValue(); - } - - /** - * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 - * - * @param v1 被除数 - * @param v2 除数 - * @param scale 精确度,如果为负值,取绝对值 - * @param roundingMode 保留小数的模式 {@link RoundingMode} - * @return 两个参数的商 - * @since 3.1.0 - */ - public static BigDecimal div(final Number v1, final Number v2, final int scale, final RoundingMode roundingMode) { - if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) { - return div((BigDecimal) v1, (BigDecimal) v2, scale, roundingMode); - } - return div(StrUtil.toStringOrNull(v1), StrUtil.toStringOrNull(v2), scale, roundingMode); - } - /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,由scale指定精确度 * @@ -747,17 +259,20 @@ public class NumberUtil { * @param scale 精确度,如果为负值,取绝对值 * @param roundingMode 保留小数的模式 {@link RoundingMode} * @return 两个参数的商 - * @since 3.0.9 + * @since 3.1.0 */ - public static BigDecimal div(final BigDecimal v1, final BigDecimal v2, int scale, final RoundingMode roundingMode) { + public static BigDecimal div(Number v1, final Number v2, int scale, final RoundingMode roundingMode) { Assert.notNull(v2, "Divisor must be not null !"); - if (null == v1) { - return BigDecimal.ZERO; + if(null == v1){ + v1 = BigDecimal.ZERO; } - if (scale < 0) { - scale = -scale; + if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) { + if (scale < 0) { + scale = -scale; + } + return ((BigDecimal) v1).divide((BigDecimal) v2, scale, roundingMode); } - return v1.divide(v2, scale, roundingMode); + return div(StrUtil.toStringOrNull(v1), StrUtil.toStringOrNull(v2), scale, roundingMode); } /** @@ -1014,7 +529,7 @@ public class NumberUtil { * @param value 值 * @return 格式化后的值 */ - public static String decimalFormat(final String pattern, final double value) { + public static String format(final String pattern, final double value) { Assert.isTrue(isValid(value), "value is NaN or Infinite!"); return new DecimalFormat(pattern).format(value); } @@ -1038,7 +553,7 @@ public class NumberUtil { * @return 格式化后的值 * @since 3.0.5 */ - public static String decimalFormat(final String pattern, final long value) { + public static String format(final String pattern, final long value) { return new DecimalFormat(pattern).format(value); } @@ -1061,8 +576,8 @@ public class NumberUtil { * @return 格式化后的值 * @since 5.1.6 */ - public static String decimalFormat(final String pattern, final Object value) { - return decimalFormat(pattern, value, null); + public static String format(final String pattern, final Object value) { + return format(pattern, value, null); } /** @@ -1085,7 +600,7 @@ public class NumberUtil { * @return 格式化后的值 * @since 5.6.5 */ - public static String decimalFormat(final String pattern, final Object value, final RoundingMode roundingMode) { + public static String format(final String pattern, final Object value, final RoundingMode roundingMode) { if (value instanceof Number) { Assert.isTrue(isValidNumber((Number) value), "value is NaN or Infinite!"); } @@ -1103,8 +618,8 @@ public class NumberUtil { * @return 格式化后的值 * @since 3.0.9 */ - public static String decimalFormatMoney(final double value) { - return decimalFormat(",##0.00", value); + public static String formatMoney(final double value) { + return format(",##0.00", value); } /** @@ -1309,82 +824,6 @@ public class NumberUtil { return true; } - // ------------------------------------------------------------------------------------------- generateXXX - - /** - * 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组 - * - * @param begin 最小数字(包含该数) - * @param end 最大数字(不包含该数) - * @param size 指定产生随机数的个数 - * @return 随机int数组 - */ - public static int[] generateRandomNumber(final int begin, final int end, final int size) { - // 种子你可以随意生成,但不能重复 - final int[] seed = ArrayUtil.range(begin, end); - return generateRandomNumber(begin, end, size, seed); - } - - /** - * 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组 - * - * @param begin 最小数字(包含该数) - * @param end 最大数字(不包含该数) - * @param size 指定产生随机数的个数 - * @param seed 种子,用于取随机数的int池 - * @return 随机int数组 - * @since 5.4.5 - */ - public static int[] generateRandomNumber(int begin, int end, final int size, final int[] seed) { - if (begin > end) { - final int temp = begin; - begin = end; - end = temp; - } - // 加入逻辑判断,确保begin= size, "Size is larger than range between begin and end!"); - Assert.isTrue(seed.length >= size, "Size is larger than seed size!"); - - final int[] ranArr = new int[size]; - // 数量你可以自己定义。 - for (int i = 0; i < size; i++) { - // 得到一个位置 - final int j = RandomUtil.randomInt(seed.length - i); - // 得到那个位置的数值 - ranArr[i] = seed[j]; - // 将最后一个未用的数字放到这里 - seed[j] = seed[seed.length - 1 - i]; - } - return ranArr; - } - - /** - * 生成不重复随机数 根据给定的最小数字和最大数字,以及随机数的个数,产生指定的不重复的数组 - * - * @param begin 最小数字(包含该数) - * @param end 最大数字(不包含该数) - * @param size 指定产生随机数的个数 - * @return 随机int数组 - */ - public static Integer[] generateBySet(int begin, int end, final int size) { - if (begin > end) { - final int temp = begin; - begin = end; - end = temp; - } - // 加入逻辑判断,确保begin set = new HashSet<>(size, 1); - while (set.size() < size) { - set.add(begin + RandomUtil.randomInt(end - begin)); - } - - return set.toArray(new Integer[0]); - } - // ------------------------------------------------------------------------------------------- range /** @@ -1412,24 +851,24 @@ public class NumberUtil { /** * 给定范围内的整数列表 * - * @param start 开始(包含) - * @param stop 结束(包含) + * @param includeStart 开始(包含) + * @param includeEnd 结束(包含) * @param step 步进 * @return 整数列表 */ - public static int[] range(final int start, final int stop, int step) { - if (start < stop) { + public static int[] range(final int includeStart, final int includeEnd, int step) { + if (includeStart < includeEnd) { step = Math.abs(step); - } else if (start > stop) { + } else if (includeStart > includeEnd) { step = -Math.abs(step); } else {// start == end - return new int[]{start}; + return new int[]{includeStart}; } - final int size = Math.abs((stop - start) / step) + 1; + final int size = Math.abs((includeEnd - includeStart) / step) + 1; final int[] values = new int[size]; int index = 0; - for (int i = start; (step > 0) ? i <= stop : i >= stop; i += step) { + for (int i = includeStart; (step > 0) ? i <= includeEnd : i >= includeEnd; i += step) { values[index] = i; index++; } diff --git a/hutool-core/src/main/java/cn/hutool/core/text/TextSimilarity.java b/hutool-core/src/main/java/cn/hutool/core/text/TextSimilarity.java index 994ff2f1d..a86d0160d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/TextSimilarity.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/TextSimilarity.java @@ -42,7 +42,7 @@ public class TextSimilarity { } final int commonLength = longestCommonSubstringLength(newStrA, newStrB); - return NumberUtil.div(commonLength, temp); + return NumberUtil.div(commonLength, temp).doubleValue(); } /** @@ -59,7 +59,7 @@ public class TextSimilarity { /** * 最长公共子串,采用动态规划算法。 其不要求所求得的字符在所给的字符串中是连续的。
- * 算法解析见:https://leetcode-cn.com/problems/longest-common-subsequence/solution/zui-chang-gong-gong-zi-xu-lie-by-leetcod-y7u0/ + * 算法解析见:zui-chang-gong-gong-zi-xu-lie-by-leetcod-y7u0 * * @param strA 字符串1 * @param strB 字符串2 diff --git a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java index 77453b431..a7b8bc6c4 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java @@ -6,6 +6,7 @@ import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.WeightRandom; import cn.hutool.core.lang.WeightRandom.WeightObj; import cn.hutool.core.math.NumberUtil; @@ -50,7 +51,7 @@ public class RandomUtil { * *

* 注意:此方法返回的{@link ThreadLocalRandom}不可以在多线程环境下共享对象,否则有重复随机数问题。 - * 见:https://www.jianshu.com/p/89dfe990295c + * 见:https://www.jianshu.com/p/89dfe990295c *

* * @return {@link ThreadLocalRandom} @@ -76,7 +77,7 @@ public class RandomUtil { * 注意:此方法获取的是伪随机序列发生器PRNG(pseudo-random number generator) * *

- * 相关说明见:https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom + * 相关说明见:how-to-solve-slow-java-securerandom * * @return {@link SecureRandom} * @since 3.1.2 @@ -90,7 +91,7 @@ public class RandomUtil { * 注意:此方法获取的是伪随机序列发生器PRNG(pseudo-random number generator) * *

- * 相关说明见:https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom + * 相关说明见:how-to-solve-slow-java-securerandom * * @param seed 随机数种子 * @return {@link SecureRandom} @@ -104,10 +105,10 @@ public class RandomUtil { /** * 获取SHA1PRNG的{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
* 注意:此方法获取的是伪随机序列发生器PRNG(pseudo-random number generator),在Linux下噪声生成时可能造成较长时间停顿。
- * see: http://ifeve.com/jvm-random-and-entropy-source/ + * see: http://ifeve.com/jvm-random-and-entropy-source/ * *

- * 相关说明见:https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom + * 相关说明见:how-to-solve-slow-java-securerandom * * @param seed 随机数种子 * @return {@link SecureRandom} @@ -443,7 +444,7 @@ public class RandomUtil { * @return 随机列表 * @since 5.2.1 */ - public static List randomEleList(final List source, final int count) { + public static List randomPick(final List source, final int count) { if (count >= source.size()) { return ListUtil.of(source); } @@ -455,6 +456,30 @@ public class RandomUtil { return result; } + /** + * 生成从种子中获取随机数字 + * + * @param size 指定产生随机数的个数 + * @param seed 种子,用于取随机数的int池 + * @return 随机int数组 + * @since 5.4.5 + */ + public static int[] randomPickInts(final int size, final int[] seed) { + Assert.isTrue(seed.length >= size, "Size is larger than seed size!"); + + final int[] ranArr = new int[size]; + // 数量你可以自己定义。 + for (int i = 0; i < size; i++) { + // 得到一个位置 + final int j = RandomUtil.randomInt(seed.length - i); + // 得到那个位置的数值 + ranArr[i] = seed[j]; + // 将最后一个未用的数字放到这里 + seed[j] = seed[seed.length - 1 - i]; + } + return ranArr; + } + /** * 随机获得列表中的一定量的不重复元素,返回Set * diff --git a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java index d3607ce39..183eb2a4b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java @@ -1,6 +1,5 @@ package cn.hutool.core.util; -import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Console; import cn.hutool.core.math.NumberUtil; import org.junit.Assert; @@ -9,7 +8,6 @@ import org.junit.Test; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; -import java.util.Set; /** * {@link NumberUtil} 单元测试类 @@ -31,7 +29,7 @@ public class NumberUtilTest { public void addTest2() { final double a = 3.15f; final double b = 4.22; - final double result = NumberUtil.add(a, b); + final double result = NumberUtil.add(a, b).doubleValue(); Assert.assertEquals(7.37, result, 2); } @@ -45,7 +43,10 @@ public class NumberUtilTest { @Test public void addTest4() { - final BigDecimal result = NumberUtil.add(new BigDecimal("133"), new BigDecimal("331")); + BigDecimal result = NumberUtil.add(new BigDecimal("133"), new BigDecimal("331")); + Assert.assertEquals(new BigDecimal("464"), result); + + result = NumberUtil.add(new BigDecimal[]{new BigDecimal("133"), new BigDecimal("331")}); Assert.assertEquals(new BigDecimal("464"), result); } @@ -55,6 +56,30 @@ public class NumberUtilTest { Assert.assertEquals(new BigDecimal("123"), result); } + @Test + public void subTest() { + BigDecimal result = NumberUtil.sub(new BigDecimal("133"), new BigDecimal("331")); + Assert.assertEquals(new BigDecimal("-198"), result); + + result = NumberUtil.sub(new BigDecimal[]{new BigDecimal("133"), new BigDecimal("331")}); + Assert.assertEquals(new BigDecimal("-198"), result); + } + + @Test + public void mulTest() { + BigDecimal result = NumberUtil.mul(new BigDecimal("133"), new BigDecimal("331")); + Assert.assertEquals(new BigDecimal("44023"), result); + + result = NumberUtil.mul(new BigDecimal[]{new BigDecimal("133"), new BigDecimal("331")}); + Assert.assertEquals(new BigDecimal("44023"), result); + } + + @Test + public void mulNullTest(){ + final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null); + Assert.assertEquals(BigDecimal.ZERO, mul); + } + @Test public void isIntegerTest() { Assert.assertTrue(NumberUtil.isInteger("-12")); @@ -90,7 +115,7 @@ public class NumberUtilTest { @Test public void divTest() { - final double result = NumberUtil.div(0, 1); + final double result = NumberUtil.div(0, 1).doubleValue(); Assert.assertEquals(0.0, result, 0); } @@ -177,7 +202,7 @@ public class NumberUtilTest { public void decimalFormatTest() { final long c = 299792458;// 光速 - final String format = NumberUtil.decimalFormat(",###", c); + final String format = NumberUtil.format(",###", c); Assert.assertEquals("299,792,458", format); } @@ -187,7 +212,7 @@ public class NumberUtilTest { final Double b = 0D; final Double c = a / b; - Console.log(NumberUtil.decimalFormat("#%", c)); + Console.log(NumberUtil.format("#%", c)); } @Test(expected = IllegalArgumentException.class) @@ -195,14 +220,14 @@ public class NumberUtilTest { final Double a = 0D; final Double b = 0D; - Console.log(NumberUtil.decimalFormat("#%", a / b)); + Console.log(NumberUtil.format("#%", a / b)); } @Test public void decimalFormatDoubleTest() { final Double c = 467.8101; - final String format = NumberUtil.decimalFormat("0.00", c); + final String format = NumberUtil.format("0.00", c); Assert.assertEquals("467.81", format); } @@ -210,11 +235,11 @@ public class NumberUtilTest { public void decimalFormatMoneyTest() { final double c = 299792400.543534534; - final String format = NumberUtil.decimalFormatMoney(c); + final String format = NumberUtil.formatMoney(c); Assert.assertEquals("299,792,400.54", format); final double value = 0.5; - final String money = NumberUtil.decimalFormatMoney(value); + final String money = NumberUtil.formatMoney(value); Assert.assertEquals("0.50", money); } @@ -373,13 +398,6 @@ public class NumberUtilTest { Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(new BigInteger("20"), BigInteger.ZERO).longValue()); } - @Test - public void mulTest(){ - final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null); - Assert.assertEquals(BigDecimal.ZERO, mul); - } - - @Test public void isPowerOfTwoTest() { Assert.assertFalse(NumberUtil.isPowerOfTwo(-1)); @@ -389,14 +407,6 @@ public class NumberUtilTest { Assert.assertFalse(NumberUtil.isPowerOfTwo(17)); } - @Test - public void generateRandomNumberTest(){ - final int[] ints = NumberUtil.generateRandomNumber(10, 20, 5); - Assert.assertEquals(5, ints.length); - final Set set = Convert.convert(Set.class, ints); - Assert.assertEquals(5, set.size()); - } - @Test public void toStrTest(){ Assert.assertEquals("1", NumberUtil.toStr(new BigDecimal("1.0000000000"))); @@ -405,15 +415,6 @@ public class NumberUtilTest { Assert.assertEquals("0", NumberUtil.toStr(new BigDecimal("9600.00000").subtract(new BigDecimal("9600.000000000")))); } - @Test - public void generateRandomNumberTest2(){ - // 检查边界 - final int[] ints = NumberUtil.generateRandomNumber(1, 8, 7); - Assert.assertEquals(7, ints.length); - final Set set = Convert.convert(Set.class, ints); - Assert.assertEquals(7, set.size()); - } - @Test public void toPlainNumberTest(){ final String num = "5344.34234e3"; @@ -421,12 +422,6 @@ public class NumberUtilTest { Assert.assertEquals("5344342.34", s); } - @Test - public void generateBySetTest(){ - final Integer[] integers = NumberUtil.generateBySet(10, 100, 5); - Assert.assertEquals(5, integers.length); - } - @Test public void isOddOrEvenTest(){ final int[] a = { 0, 32, -32, 123, -123 }; @@ -456,7 +451,7 @@ public class NumberUtilTest { @Test public void divIntegerTest(){ - final BigDecimal div = NumberUtil.div(100101300, (Number) 100); + final BigDecimal div = NumberUtil.div(100101300, 100); Assert.assertEquals(1001013, div.intValue()); } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/RandomUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/RandomUtilTest.java index 336d7b896..25c4c67a0 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/RandomUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/RandomUtilTest.java @@ -1,7 +1,9 @@ package cn.hutool.core.util; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Console; +import cn.hutool.core.math.NumberUtil; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -72,4 +74,12 @@ public class RandomUtilTest { } } } + + @Test + public void generateRandomNumberTest(){ + final int[] ints = RandomUtil.randomPickInts(5, NumberUtil.range(5, 20)); + Assert.assertEquals(5, ints.length); + final Set set = Convert.convert(Set.class, ints); + Assert.assertEquals(5, set.size()); + } } diff --git a/hutool-extra/src/main/java/cn/hutool/extra/management/oshi/CpuInfo.java b/hutool-extra/src/main/java/cn/hutool/extra/management/oshi/CpuInfo.java index 946d6babf..5657868e0 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/management/oshi/CpuInfo.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/management/oshi/CpuInfo.java @@ -161,7 +161,7 @@ public class CpuInfo { * @return 总CPU使用率 */ public double getUsed() { - return NumberUtil.sub(100, this.free); + return NumberUtil.sub(100, this.free).doubleValue(); } @Override diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java index efdbbd0c8..d187c267d 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -178,7 +178,7 @@ public class JSONUtilTest { @Test public void customValueTest() { final JSONObject jsonObject = JSONUtil.createObj() - .set("test2", (JSONString) () -> NumberUtil.decimalFormat("#.0", 12.00D)); + .set("test2", (JSONString) () -> NumberUtil.format("#.0", 12.00D)); Assert.assertEquals("{\"test2\":12.0}", jsonObject.toString()); } diff --git a/hutool-swing/src/main/java/cn/hutool/swing/img/Img.java b/hutool-swing/src/main/java/cn/hutool/swing/img/Img.java index 7b0fce64e..c9a033881 100755 --- a/hutool-swing/src/main/java/cn/hutool/swing/img/Img.java +++ b/hutool-swing/src/main/java/cn/hutool/swing/img/Img.java @@ -237,9 +237,9 @@ public class Img implements Serializable { ImgUtil.toBufferedImage(srcImg, this.targetImageType)); } else { // 缩放后的图片宽 - final int width = NumberUtil.mul((Number) srcImg.getWidth(null), scale).intValue(); + final int width = NumberUtil.mul(srcImg.getWidth(null), scale).intValue(); // 缩放后的图片高 - final int height = NumberUtil.mul((Number) srcImg.getHeight(null), scale).intValue(); + final int height = NumberUtil.mul(srcImg.getHeight(null), scale).intValue(); scale(width, height); } return this; @@ -280,8 +280,8 @@ public class Img implements Serializable { if (ImgUtil.IMAGE_TYPE_PNG.equals(this.targetImageType)) { // png特殊处理,借助AffineTransform可以实现透明度保留 - final double sx = NumberUtil.div(width, srcWidth);// 宽度缩放比 - final double sy = NumberUtil.div(height, srcHeight); // 高度缩放比 + final double sx = NumberUtil.div(width, srcWidth).doubleValue();// 宽度缩放比 + final double sy = NumberUtil.div(height, srcHeight).doubleValue(); // 高度缩放比 this.targetImage = ImgUtil.transform(AffineTransform.getScaleInstance(sx, sy), ImgUtil.toBufferedImage(srcImg, this.targetImageType)); } else { @@ -304,8 +304,8 @@ public class Img implements Serializable { Image srcImage = getValidSrcImg(); int srcHeight = srcImage.getHeight(null); int srcWidth = srcImage.getWidth(null); - final double heightRatio = NumberUtil.div(height, srcHeight); - final double widthRatio = NumberUtil.div(width, srcWidth); + final double heightRatio = NumberUtil.div(height, srcHeight).doubleValue(); + final double widthRatio = NumberUtil.div(width, srcWidth).doubleValue(); // 浮点数之间的等值判断,基本数据类型不能用==比较,包装数据类型不能用equals来判断。 if (NumberUtil.equals(heightRatio, widthRatio)) { @@ -411,7 +411,7 @@ public class Img implements Serializable { final int height = srcImage.getHeight(null); // 通过弧度占比计算弧度 - arc = NumberUtil.mul(arc, Math.min(width, height)); + arc = NumberUtil.mul(arc, Math.min(width, height)).doubleValue(); final BufferedImage targetImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final Graphics2D g2 = targetImage.createGraphics(); @@ -590,7 +590,7 @@ public class Img implements Serializable { /** * 旋转图片为指定角度
- * 来自:http://blog.51cto.com/cping1982/130066 + * 来自:http://blog.51cto.com/cping1982/130066 * * @param degree 旋转角度 * @return 旋转后的图片