diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index 56e5bfe50..7287eaf52 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -1583,6 +1583,57 @@ public class CollUtil { return count; } + /** + * 获取匹配规则定义中匹配到元素的第一个位置
+ * 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 + * + * @param 元素类型 + * @param collection 集合 + * @param matcher 匹配器,为空则全部匹配 + * @return 第一个位置 + * @since 5.6.6 + */ + public static int indexOf(Collection collection, Matcher matcher) { + if (isNotEmpty(collection)) { + int index = 0; + for (T t : collection) { + if (null == matcher || matcher.match(t)) { + return index; + } + index++; + } + } + return -1; + } + + /** + * 获取匹配规则定义中匹配到元素的最后位置
+ * 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 + * + * @param 元素类型 + * @param collection 集合 + * @param matcher 匹配器,为空则全部匹配 + * @return 最后一个位置 + * @since 5.6.6 + */ + public static int lastIndexOf(Collection collection, Matcher matcher) { + if(collection instanceof List){ + // List的查找最后一个有优化算法 + return ListUtil.lastIndexOf((List)collection, matcher); + } + int matchIndex = -1; + if (isNotEmpty(collection)) { + int index = collection.size(); + for (T t : collection) { + if (null == matcher || matcher.match(t)) { + matchIndex = index; + } + index--; + } + } + return matchIndex; + } + /** * 获取匹配规则定义中匹配到元素的所有位置
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java index a2165839a..13d435089 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ListUtil.java @@ -2,7 +2,6 @@ package cn.hutool.core.collection; import cn.hutool.core.comparator.PinyinComparator; import cn.hutool.core.comparator.PropertyComparator; -import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Editor; import cn.hutool.core.lang.Matcher; import cn.hutool.core.util.ArrayUtil; @@ -455,6 +454,30 @@ public class ListUtil { return list2; } + /** + * 获取匹配规则定义中匹配到元素的最后位置
+ * 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。 + * + * @param 元素类型 + * @param list List集合 + * @param matcher 匹配器,为空则全部匹配 + * @return 最后一个位置 + * @since 5.6.6 + */ + public static int lastIndexOf(List list, Matcher matcher) { + if (null != list) { + final int size = list.size(); + if(size > 0){ + for(int i = size -1; i >= 0; i--){ + if (null == matcher || matcher.match(list.get(i))) { + return i; + } + } + } + } + return -1; + } + /** * 获取匹配规则定义中匹配到元素的所有位置 * @@ -465,17 +488,7 @@ public class ListUtil { * @since 5.2.5 */ public static int[] indexOfAll(List list, Matcher matcher) { - final List indexList = new ArrayList<>(); - if (null != list) { - int index = 0; - for (T t : list) { - if (null == matcher || matcher.match(t)) { - indexList.add(index); - } - index++; - } - } - return Convert.convert(int[].class, indexList); + return CollUtil.indexOfAll(list, matcher); } /** 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 3aae4956c..5f052a3af 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 @@ -163,14 +163,34 @@ public class ArrayUtil extends PrimitiveArrayUtil { */ @SuppressWarnings("unchecked") public static T firstMatch(Matcher matcher, T... array) { + final int index = matchIndex(matcher, array); + if(index < 0){ + return null; + } + + return array[index]; + } + + /** + * 返回数组中第一个匹配规则的值的位置 + * + * @param 数组元素类型 + * @param matcher 匹配接口,实现此接口自定义匹配规则 + * @param array 数组 + * @return 匹配到元素的位置,-1表示未匹配到 + * @since 5.6.6 + */ + @SuppressWarnings("unchecked") + public static int matchIndex(Matcher matcher, T... array) { if (isNotEmpty(array)) { - for (final T val : array) { - if (matcher.match(val)) { - return val; + for(int i = 0; i < array.length; i++){ + if(matcher.match(array[i])){ + return i; } } } - return null; + + return INDEX_NOT_FOUND; } /** @@ -739,14 +759,7 @@ public class ArrayUtil extends PrimitiveArrayUtil { * @since 3.0.7 */ public static int indexOf(T[] array, Object value) { - if (null != array) { - for (int i = 0; i < array.length; i++) { - if (ObjectUtil.equal(value, array[i])) { - return i; - } - } - } - return INDEX_NOT_FOUND; + return matchIndex((obj)-> ObjectUtil.equal(value, obj), array); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java index 076dd64fb..446716cb3 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/CollUtilTest.java @@ -686,6 +686,29 @@ public class CollUtilTest { Assert.assertEquals(Integer.valueOf(1), countMap.get("d")); } + @Test + public void indexOfTest() { + ArrayList list = CollUtil.newArrayList("a", "b", "c", "c", "a", "b", "d"); + final int i = CollUtil.indexOf(list, (str) -> str.charAt(0) == 'c'); + Assert.assertEquals(2, i); + } + + @Test + public void lastIndexOfTest() { + // List有优化 + ArrayList list = CollUtil.newArrayList("a", "b", "c", "c", "a", "b", "d"); + final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'c'); + Assert.assertEquals(3, i); + } + + @Test + public void lastIndexOfSetTest() { + Set list = CollUtil.set(true, "a", "b", "c", "c", "a", "b", "d"); + // 去重后c排第三 + final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'c'); + Assert.assertEquals(2, i); + } + @Test public void pageTest(){ List objects = CollUtil.newArrayList(); diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java index fad6d5da6..fb8501d90 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java @@ -80,9 +80,19 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader this.rid) { return this.boundSheetRecords.get(this.rid > -1 ? this.rid : this.curRid).getSheetname(); } + return null; } @@ -179,7 +194,11 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader 0){ - return sheetIndex; - } + } catch (NumberFormatException ignore) { + // 如果用于传入非数字,按照sheet名称对待 + this.sheetName = idOrRidOrSheetName; } - throw new IllegalArgumentException("Invalid rId or id or sheetName: " + idOrRidOrSheetName); - } - - /** - * 通过sheet名称获取其位置(rid) - * @param sheetName sheet名称 - * @return 位置,-1表示未找到 - * @since 5.6.6 - */ - private int getSheetIndexByName(String sheetName){ - final List boundSheetRecords = this.boundSheetRecords; - final int size = boundSheetRecords.size(); - for(int i = 0; i < size; i++){ - if(StrUtil.equals(sheetName, boundSheetRecords.get(i).getSheetname())){ - return i; - } - } return -1; } // ---------------------------------------------------------------------------------------------- Private method end diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java index 01fe55749..eef707551 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java @@ -75,24 +75,24 @@ public interface ExcelSaxReader { * 开始读取Excel * * @param path 文件路径 - * @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet + * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet * @return this * @throws POIException POI异常 */ - default T read(String path, int rid) throws POIException { - return read(FileUtil.file(path), rid); + default T read(String path, int idOrRidOrSheetName) throws POIException { + return read(FileUtil.file(path), idOrRidOrSheetName); } /** * 开始读取Excel * * @param path 文件路径 - * @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet + * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet * @return this * @throws POIException POI异常 */ - default T read(String path, String rid) throws POIException { - return read(FileUtil.file(path), rid); + default T read(String path, String idOrRidOrSheetName) throws POIException { + return read(FileUtil.file(path), idOrRidOrSheetName); } /** diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java index 454f8fdba..3429d9356 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java @@ -9,6 +9,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.poi.excel.cell.FormulaCellValue; import cn.hutool.poi.excel.sax.Excel03SaxReader; import cn.hutool.poi.excel.sax.handler.RowHandler; +import cn.hutool.poi.exceptions.POIException; import org.apache.poi.ss.usermodel.CellStyle; import org.junit.Assert; import org.junit.Ignore; @@ -41,10 +42,24 @@ public class ExcelSaxReadTest { public void excel03Test() { Excel03SaxReader reader = new Excel03SaxReader(createRowHandler()); reader.read("aaa.xls", 1); + // Console.log("Sheet index: [{}], Sheet name: [{}]", reader.getSheetIndex(), reader.getSheetName()); ExcelUtil.readBySax("aaa.xls", 1, createRowHandler()); } + @Test + public void excel03ByNameTest() { + Excel03SaxReader reader = new Excel03SaxReader(createRowHandler()); + reader.read("aaa.xls", "校园入学"); + } + + @Test(expected = POIException.class) + public void excel03ByNameErrorTest() { + // sheet名称不存在则报错 + Excel03SaxReader reader = new Excel03SaxReader(createRowHandler()); + reader.read("aaa.xls", "校园入学1"); + } + @Test @Ignore public void readBlankLineTest() { @@ -124,7 +139,6 @@ public class ExcelSaxReadTest { @Test public void formulaRead03Test() { - Console.log(FileUtil.file("data_for_sax_test.xls")); List rows = new ArrayList<>(); ExcelUtil.readBySax("data_for_sax_test.xls", -1, (i, i1, list) -> { if(list.size() > 1){