diff --git a/CHANGELOG.md b/CHANGELOG.md index 2896d1cd0..41778fc0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,14 @@ ------------------------------------------------------------------------------------------------------------- -# 5.4.7 (2020-10-31) +# 5.4.8 (2020-11-03) ### 新特性 +* 【core 】 NumberUtil.parseInt等支持123,2.00这类数字(issue#I23ORQ@Gitee) +* 【core 】 增加ArrayUtil.isSub、indexOfSub、lastIndexOfSub方法(issue#I23O1K@Gitee) + ### Bug修复 +* 【core 】 修复DateUtil.current使用System.nanoTime的问题(issue#1198@Github) ------------------------------------------------------------------------------------------------------------- @@ -19,7 +23,7 @@ * 【core 】 CollUtil.map忽略空值改规则为原数组中的元素和处理后的元素都会忽略空值(issue#I22N08@Gitee) * 【http 】 增加SoapClient增加addSOAPHeader重载 * 【http 】 ArrayUtil增加containsAll方法 -* 【http 】 增加CharsetDetector +* 【core 】 增加CharsetDetector * 【cron 】 增加CronTask,监听支持获取id(issue#I23315@Gitee) ### Bug修复 diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index 5b8df51ed..e5bcc8827 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -123,11 +123,10 @@ public class DateUtil extends CalendarUtil { /** * 当前时间的时间戳 * - * @param isNano 是否为高精度时间 * @return 时间 */ - public static long current(boolean isNano) { - return isNano ? System.nanoTime() : System.currentTimeMillis(); + public static long current() { + return System.currentTimeMillis(); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TimeInterval.java b/hutool-core/src/main/java/cn/hutool/core/date/TimeInterval.java index 8edd5cfe8..8168d2e70 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/TimeInterval.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/TimeInterval.java @@ -4,7 +4,7 @@ import java.io.Serializable; /** * 计时器
- * 计算某个过程花费的时间,精确到毫秒 + * 计算某个过程花费的时间,精确到毫秒或纳秒 * * @author Looly */ @@ -34,7 +34,7 @@ public class TimeInterval implements Serializable { * @return 开始计时并返回当前时间 */ public long start() { - time = DateUtil.current(isNano); + time = getTime(isNano); return time; } @@ -42,7 +42,7 @@ public class TimeInterval implements Serializable { * @return 重新计时并返回从开始到当前的持续时间 */ public long intervalRestart() { - long now = DateUtil.current(isNano); + long now = getTime(isNano); long d = now - time; time = now; return d; @@ -55,7 +55,7 @@ public class TimeInterval implements Serializable { * @since 3.0.1 */ public TimeInterval restart() { - time = DateUtil.current(isNano); + time = getTime(isNano); return this; } @@ -68,7 +68,7 @@ public class TimeInterval implements Serializable { * @return 从开始到当前的间隔时间(毫秒数) */ public long interval() { - return DateUtil.current(isNano) - time; + return getTime(isNano) - time; } /** @@ -135,4 +135,13 @@ public class TimeInterval implements Serializable { return intervalMs() / DateUnit.WEEK.getMillis(); } + /** + * 获取时间的毫秒或纳秒数,纳秒非时间戳 + * + * @param isNano 是否为高精度时间 + * @return 时间 + */ + private static long getTime(boolean isNano) { + return isNano ? System.nanoTime() : System.currentTimeMillis(); + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java index 78084e7ca..b3f3f77e4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java @@ -317,9 +317,9 @@ public class ArrayUtil { /** * 返回数组中第一个匹配规则的值 * - * @param 数组元素类型 + * @param 数组元素类型 * @param matcher 匹配接口,实现此接口自定义匹配规则 - * @param array 数组 + * @param array 数组 * @return 非空元素,如果不存在非空元素或数组为空,返回{@code null} * @since 3.0.7 */ @@ -327,7 +327,7 @@ public class ArrayUtil { public static T firstMatch(Matcher matcher, T... array) { if (isNotEmpty(array)) { for (final T val : array) { - if(matcher.match(val)){ + if (matcher.match(val)) { return val; } } @@ -4308,17 +4308,17 @@ public class ArrayUtil { /** * 按照指定规则,将一种类型的数组转换为另一种类型 * - * @param array 被转换的数组 + * @param array 被转换的数组 * @param targetComponentType 目标的元素类型 - * @param func 转换规则函数 - * @param 原数组类型 - * @param 目标数组类型 + * @param func 转换规则函数 + * @param 原数组类型 + * @param 目标数组类型 * @return 转换后的数组 * @since 5.4.2 */ - public static R[] map(T[] array, Class targetComponentType, Function func){ + public static R[] map(T[] array, Class targetComponentType, Function func) { final R[] result = newArray(targetComponentType, array.length); - for(int i=0; i< array.length; i++){ + for (int i = 0; i < array.length; i++) { result[i] = func.apply(array[i]); } return result; @@ -4326,16 +4326,17 @@ public class ArrayUtil { /** * 判断两个数组是否相等,判断依据包括数组长度和每个元素都相等。 + * * @param array1 数组1 * @param array2 数组2 * @return 是否相等 * @since 5.4.2 */ - public static boolean equals(Object array1, Object array2){ - if(array1 == array2){ + public static boolean equals(Object array1, Object array2) { + if (array1 == array2) { return true; } - if(hasNull(array1, array2)){ + if (hasNull(array1, array2)) { return false; } @@ -4343,7 +4344,7 @@ public class ArrayUtil { Assert.isTrue(isArray(array2), "Second is not a Array !"); // 数组类型一致性判断 - if(array1.getClass() != array2.getClass()){ + if (array1.getClass() != array2.getClass()) { return false; } @@ -4368,4 +4369,72 @@ public class ArrayUtil { return Arrays.deepEquals((Object[]) array1, (Object[]) array2); } } + + /** + * 查找子数组的位置 + * + * @param array 数组 + * @param subArray 子数组 + * @param 数组元素类型 + * @return 子数组的开始位置,即子数字第一个元素在数组中的位置 + * @since 5.4.8 + */ + public static boolean isSub(T[] array, T[] subArray) { + return indexOfSub(array, subArray) > INDEX_NOT_FOUND; + } + + /** + * 查找子数组的位置 + * + * @param array 数组 + * @param subArray 子数组 + * @param 数组元素类型 + * @return 子数组的开始位置,即子数字第一个元素在数组中的位置 + * @since 5.4.8 + */ + public static int indexOfSub(T[] array, T[] subArray) { + if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) { + return INDEX_NOT_FOUND; + } + int firstIndex = indexOf(array, subArray[0]); + if (firstIndex < 0 || firstIndex + subArray.length > array.length) { + return INDEX_NOT_FOUND; + } + + for (int i = 0; i < subArray.length; i++) { + if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) { + return INDEX_NOT_FOUND; + } + } + + return firstIndex; + } + + /** + * 查找最后一个子数组的开始位置 + * + * @param array 数组 + * @param subArray 子数组 + * @param 数组元素类型 + * @return 最后一个子数组的开始位置,即子数字第一个元素在数组中的位置 + * @since 5.4.8 + */ + public static int lastIndexOfSub(T[] array, T[] subArray) { + if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) { + return INDEX_NOT_FOUND; + } + + int firstIndex = lastIndexOf(array, subArray[0]); + if (firstIndex < 0 || firstIndex + subArray.length > array.length) { + return INDEX_NOT_FOUND; + } + + for (int i = 0; i < subArray.length; i++) { + if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) { + return INDEX_NOT_FOUND; + } + } + + return firstIndex; + } } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java index 120d32f39..c5e11acb6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java @@ -2511,6 +2511,10 @@ public class NumberUtil { * @return 去掉标识的字符串 */ private static String removeNumberFlag(String number) { + // 去掉千位分隔符 + if(StrUtil.contains(number, CharUtil.COMMA)){ + number = StrUtil.removeAll(number, CharUtil.COMMA); + } // 去掉类型标识的结尾 final int lastPos = number.length() - 1; final char lastCharUpper = Character.toUpperCase(number.charAt(lastPos)); diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java index ab68a122a..fb563707e 100644 --- a/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/date/DateUtilTest.java @@ -265,11 +265,11 @@ public class DateUtilTest { @Test public void currentTest() { - long current = DateUtil.current(false); + long current = DateUtil.current(); String currentStr = String.valueOf(current); Assert.assertEquals(13, currentStr.length()); - long currentNano = DateUtil.current(true); + long currentNano = DateUtil.current(); String currentNanoStr = String.valueOf(currentNano); Assert.assertNotNull(currentNanoStr); } diff --git a/hutool-core/src/test/java/cn/hutool/core/util/ArrayUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/ArrayUtilTest.java index 0d504d886..948ea96c0 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/ArrayUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/ArrayUtilTest.java @@ -317,4 +317,64 @@ public class ArrayUtilTest { String[] hasNull = {"aa", "bb", "cc", null, "bb", "dd"}; Assert.assertFalse(ArrayUtil.isAllNotNull(hasNull)); } + + @Test + public void indexOfSubTest() { + Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A}; + Integer[] b = {0x56, 0x78}; + Integer[] c = {0x12, 0x56}; + Integer[] d = {0x78, 0x9A}; + Integer[] e = {0x78, 0x9A, 0x10}; + + int i = ArrayUtil.indexOfSub(a, b); + Assert.assertEquals(2, i); + + i = ArrayUtil.indexOfSub(a, c); + Assert.assertEquals(-1, i); + + i = ArrayUtil.indexOfSub(a, d); + Assert.assertEquals(3, i); + + i = ArrayUtil.indexOfSub(a, e); + Assert.assertEquals(-1, i); + + i = ArrayUtil.indexOfSub(a, null); + Assert.assertEquals(-1, i); + + i = ArrayUtil.indexOfSub(null, null); + Assert.assertEquals(-1, i); + + i = ArrayUtil.indexOfSub(null, b); + Assert.assertEquals(-1, i); + } + + @Test + public void lastIndexOfSubTest() { + Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A}; + Integer[] b = {0x56, 0x78}; + Integer[] c = {0x12, 0x56}; + Integer[] d = {0x78, 0x9A}; + Integer[] e = {0x78, 0x9A, 0x10}; + + int i = ArrayUtil.lastIndexOfSub(a, b); + Assert.assertEquals(2, i); + + i = ArrayUtil.lastIndexOfSub(a, c); + Assert.assertEquals(-1, i); + + i = ArrayUtil.lastIndexOfSub(a, d); + Assert.assertEquals(3, i); + + i = ArrayUtil.lastIndexOfSub(a, e); + Assert.assertEquals(-1, i); + + i = ArrayUtil.lastIndexOfSub(a, null); + Assert.assertEquals(-1, i); + + i = ArrayUtil.lastIndexOfSub(null, null); + Assert.assertEquals(-1, i); + + i = ArrayUtil.lastIndexOfSub(null, b); + Assert.assertEquals(-1, i); + } } 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 10584a2a8..cbd632a0f 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 @@ -221,6 +221,22 @@ public class NumberUtilTest { int v7 = NumberUtil.parseInt("0"); Assert.assertEquals(0, v7); } + + @Test + public void parseIntTest2() { + // from 5.4.8 issue#I23ORQ@Gitee + // 千位分隔符去掉 + int v1 = NumberUtil.parseInt("1,482.00"); + Assert.assertEquals(1482, v1); + } + + @Test + public void parseNumberTest() { + // from 5.4.8 issue#I23ORQ@Gitee + // 千位分隔符去掉 + int v1 = NumberUtil.parseNumber("1,482.00").intValue(); + Assert.assertEquals(1482, v1); + } @Test public void parseLongTest() { diff --git a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java index 3785330c0..58104b768 100644 --- a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java +++ b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternTest.java @@ -18,8 +18,8 @@ public class CronPatternTest { CronPattern pattern; // 任何时间匹配 pattern = new CronPattern("* * * * * *"); - Assert.assertTrue(pattern.match(DateUtil.current(false), true)); - Assert.assertTrue(pattern.match(DateUtil.current(false), false)); + Assert.assertTrue(pattern.match(DateUtil.current(), true)); + Assert.assertTrue(pattern.match(DateUtil.current(), false)); } @Test @@ -30,7 +30,7 @@ public class CronPatternTest { // 任何时间匹配 pattern = new CronPattern("* * * * *"); for(int i = 0; i < 1; i++) { - Assert.assertTrue(pattern.match(DateUtil.current(false), false)); + Assert.assertTrue(pattern.match(DateUtil.current(), false)); } }