From d12fcab0e830daf43a96dfa5353977c4a7fcc1b8 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 9 Sep 2024 21:25:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DArrayUtil.lastIndexOfSub?= =?UTF-8?q?=E6=AD=BB=E5=BE=AA=E7=8E=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../java/cn/hutool/core/util/ArrayUtil.java | 41 +++++++++++++------ .../cn/hutool/core/util/IssueIAQ16ETest.java | 34 +++++++++++++++ 3 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/util/IssueIAQ16ETest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1579710..4ddd2c1c8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.33(2024-09-06) +# 5.8.33(2024-09-09) ### 🐣新特性 * 【core 】 SyncFinisher增加setExecutorService方法(issue#IANKQ1@Gitee) @@ -15,6 +15,7 @@ * 【json 】 修复JSONConfig.setDateFormat设置后toBean无效问题(issue#3713@Github) * 【core 】 修复RegexPool.CHINESE_NAME范围太大的问题(issue#IAOGDR@Gitee) * 【http 】 修复重定向没有按照RFC7231规范跳转的问题,修改为除了307外重定向使用GET方式(issue#3722@Github) +* 【core 】 修复ArrayUtil.lastIndexOfSub死循环问题(issue#IAQ16E@Gitee) ------------------------------------------------------------------------------------------------------------- **# 5.8.32(2024-08-30) 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 3104da84a..d7a249ced 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java @@ -6,10 +6,7 @@ import cn.hutool.core.collection.UniqueKeySet; import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.exceptions.UtilException; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.Editor; -import cn.hutool.core.lang.Filter; -import cn.hutool.core.lang.Matcher; +import cn.hutool.core.lang.*; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrJoiner; @@ -1864,29 +1861,49 @@ public class ArrayUtil extends PrimitiveArrayUtil { * 查找最后一个子数组的开始位置 * * @param array 数组 - * @param endInclude 查找结束的位置(包含) + * @param endInclude 查找结束的位置(包含),-1表示最后一位 * @param subArray 子数组 * @param 数组元素类型 * @return 最后一个子数组的开始位置,即子数字第一个元素在数组中的位置 * @since 5.4.8 */ public static int lastIndexOfSub(T[] array, int endInclude, T[] subArray) { - if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length || endInclude < 0) { + if (isEmpty(array) || isEmpty(subArray)) { + return INDEX_NOT_FOUND; + } + if(endInclude < 0){ + endInclude += array.length; + } + if(endInclude < 0){ + return INDEX_NOT_FOUND; + } + if(endInclude > array.length - 1){ + // 结束位置超过最大值 + endInclude = array.length - 1; + } + if(subArray.length - 1 > endInclude){ + // 剩余长度不足 return INDEX_NOT_FOUND; } - int firstIndex = lastIndexOf(array, subArray[0]); - if (firstIndex < 0 || firstIndex + subArray.length > array.length) { + final int lastEleIndex = lastIndexOf(array, subArray[subArray.length - 1], endInclude); + if (lastEleIndex < 0 || lastEleIndex < subArray.length - 1) { return INDEX_NOT_FOUND; } - for (int i = 0; i < subArray.length; i++) { - if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) { - return lastIndexOfSub(array, firstIndex - 1, subArray); + // 匹配字串后续字符 + boolean isAllMatch = true; + for (int i = 0; i < subArray.length - 1; i++) { + if (ObjectUtil.notEqual(array[i + lastEleIndex - subArray.length + 1], subArray[i])) { + isAllMatch =false; + break; } } + if(isAllMatch){ + return lastEleIndex - subArray.length + 1; + } - return firstIndex; + return lastIndexOfSub(array, lastEleIndex - 1, subArray); } // O(n)时间复杂度检查数组是否有序 diff --git a/hutool-core/src/test/java/cn/hutool/core/util/IssueIAQ16ETest.java b/hutool-core/src/test/java/cn/hutool/core/util/IssueIAQ16ETest.java new file mode 100644 index 000000000..64a7c93b9 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/util/IssueIAQ16ETest.java @@ -0,0 +1,34 @@ +package cn.hutool.core.util; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class IssueIAQ16ETest { + @Test + void lastIndexOfSubTest() { + Integer[] bigBytes = new Integer[]{1, 2, 2, 2, 3, 2, 2, 2, 3}; + Integer[] subBytes = new Integer[]{2, 2}; + final int i = ArrayUtil.lastIndexOfSub(bigBytes, subBytes); + Assertions.assertEquals(6, i); + } + + @Test + void lastIndexOfSubTest2() { + Integer[] bigBytes = new Integer[]{1, 2, 2, 2, 3, 2, 2, 2, 3, 4, 5}; + Integer[] subBytes = new Integer[]{2, 2, 2, 3}; + final int i = ArrayUtil.lastIndexOfSub(bigBytes, subBytes); + Assertions.assertEquals(5, i); + Assertions.assertEquals(5, i); + } + + @Test + public void lastIndexOfSubTest3() { + Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A}; + Integer[] b = {0x56, 0x78}; + + int i = ArrayUtil.lastIndexOfSub(a, b); + assertEquals(2, i); + } +}