diff --git a/CHANGELOG.md b/CHANGELOG.md index b498a0294..0a3711ac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ * 【core 】 修复SqlFormatter部分SQL空指针问题(issue#I3XS44@Gitee) * 【core 】 修复DateRange计算问题(issue#I3Y1US@Gitee) * 【core 】 修复BeanCopier中setFieldNameEditor失效问题(pr#349@Gitee) +* 【core 】 修复ArrayUtil.indexOfSub查找bug(pr#349@Gitee) ------------------------------------------------------------------------------------------------------------- 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 794a42aae..dcdbd9df7 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 @@ -183,8 +183,23 @@ public class ArrayUtil extends PrimitiveArrayUtil { */ @SuppressWarnings("unchecked") public static int matchIndex(Matcher matcher, T... array) { + return matchIndex(matcher, 0, array); + } + + /** + * 返回数组中第一个匹配规则的值的位置 + * + * @param 数组元素类型 + * @param matcher 匹配接口,实现此接口自定义匹配规则 + * @param beginIndexInclude 检索开始的位置 + * @param array 数组 + * @return 匹配到元素的位置,-1表示未匹配到 + * @since 5.7.3 + */ + @SuppressWarnings("unchecked") + public static int matchIndex(Matcher matcher, int beginIndexInclude, T... array) { if (isNotEmpty(array)) { - for (int i = 0; i < array.length; i++) { + for (int i = beginIndexInclude; i < array.length; i++) { if (matcher.match(array[i])) { return i; } @@ -728,6 +743,20 @@ public class ArrayUtil extends PrimitiveArrayUtil { // ------------------------------------------------------------------- indexOf and lastIndexOf and contains + /** + * 返回数组中指定元素所在位置,未找到返回{@link #INDEX_NOT_FOUND} + * + * @param 数组类型 + * @param array 数组 + * @param value 被检查的元素 + * @param beginIndexInclude 检索开始的位置 + * @return 数组中指定元素所在位置,未找到返回{@link #INDEX_NOT_FOUND} + * @since 3.0.7 + */ + public static int indexOf(T[] array, Object value, int beginIndexInclude) { + return matchIndex((obj) -> ObjectUtil.equal(value, obj), beginIndexInclude, array); + } + /** * 返回数组中指定元素所在位置,未找到返回{@link #INDEX_NOT_FOUND} * @@ -770,8 +799,25 @@ public class ArrayUtil extends PrimitiveArrayUtil { * @since 3.0.7 */ public static int lastIndexOf(T[] array, Object value) { - if (null != array) { - for (int i = array.length - 1; i >= 0; i--) { + if (isEmpty(array)) { + return INDEX_NOT_FOUND; + } + return lastIndexOf(array, value, array.length - 1); + } + + /** + * 返回数组中指定元素所在最后的位置,未找到返回{@link #INDEX_NOT_FOUND} + * + * @param 数组类型 + * @param array 数组 + * @param value 被检查的元素 + * @param endInclude 查找方式为从后向前查找,查找的数组结束位置,一般为array.length-1 + * @return 数组中指定元素所在位置,未找到返回{@link #INDEX_NOT_FOUND} + * @since 5.7.3 + */ + public static int lastIndexOf(T[] array, Object value, int endInclude) { + if (isNotEmpty(array)) { + for (int i = endInclude; i >= 0; i--) { if (ObjectUtil.equal(value, array[i])) { return i; } @@ -1146,7 +1192,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { * @since 5.3.3 */ public static String join(T[] array, CharSequence conjunction, Editor editor) { - return StrJoiner.of(conjunction).append(array, (t)-> String.valueOf(editor.edit(t))).toString(); + return StrJoiner.of(conjunction).append(array, (t) -> String.valueOf(editor.edit(t))).toString(); } /** @@ -1658,17 +1704,30 @@ public class ArrayUtil extends PrimitiveArrayUtil { * @since 5.4.8 */ public static int indexOfSub(T[] array, T[] subArray) { + return indexOfSub(array, 0, subArray); + } + + /** + * 查找子数组的位置 + * + * @param array 数组 + * @param subArray 子数组 + * @param 数组元素类型 + * @return 子数组的开始位置,即子数字第一个元素在数组中的位置 + * @since 5.4.8 + */ + public static int indexOfSub(T[] array, int beginInclude, T[] subArray) { if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) { return INDEX_NOT_FOUND; } - int firstIndex = indexOf(array, subArray[0]); + int firstIndex = indexOf(array, subArray[0], beginInclude); 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 indexOfSub(array, firstIndex + 1, subArray); } } @@ -1685,7 +1744,23 @@ public class ArrayUtil extends PrimitiveArrayUtil { * @since 5.4.8 */ public static int lastIndexOfSub(T[] array, T[] subArray) { - if (isEmpty(array) || isEmpty(subArray) || subArray.length > array.length) { + if (isEmpty(array) || isEmpty(subArray)) { + return INDEX_NOT_FOUND; + } + return lastIndexOfSub(array, array.length - 1, subArray); + } + + /** + * 查找最后一个子数组的开始位置 + * + * @param array 数组 + * @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) { return INDEX_NOT_FOUND; } @@ -1696,7 +1771,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { for (int i = 0; i < subArray.length; i++) { if (false == ObjectUtil.equal(array[i + firstIndex], subArray[i])) { - return INDEX_NOT_FOUND; + return lastIndexOfSub(array, firstIndex - 1, subArray); } } 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 da5dbe682..3404d2b98 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 @@ -356,6 +356,14 @@ public class ArrayUtilTest { Assert.assertEquals(-1, i); } + @Test + public void indexOfSubTest2(){ + Integer[] a = {0x12, 0x56, 0x34, 0x56, 0x78, 0x9A}; + Integer[] b = {0x56, 0x78}; + int i = ArrayUtil.indexOfSub(a, b); + Assert.assertEquals(3, i); + } + @Test public void lastIndexOfSubTest() { Integer[] a = {0x12, 0x34, 0x56, 0x78, 0x9A}; @@ -386,6 +394,14 @@ public class ArrayUtilTest { Assert.assertEquals(-1, i); } + @Test + public void lastIndexOfSubTest2(){ + Integer[] a = {0x12, 0x56, 0x78, 0x56, 0x21, 0x9A}; + Integer[] b = {0x56, 0x78}; + int i = ArrayUtil.indexOfSub(a, b); + Assert.assertEquals(1, i); + } + @Test public void reverseTest(){ int[] a = {1,2,3,4};