diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/util/ObjUtil.java b/hutool-core/src/main/java/cn/hutool/v7/core/util/ObjUtil.java index d59b87fe9..042cb969d 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/util/ObjUtil.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/util/ObjUtil.java @@ -88,8 +88,8 @@ public class ObjUtil { *
  • 数组:返回数组长度;
  • *
  • {@link CharSequence}:返回{@link CharSequence#length()};
  • *
  • {@link Collection}:返回{@link Collection#size()};
  • - *
  • {@link Iterator}或{@link Iterable}:可迭代的元素数量;
  • - *
  • {@link Enumeration}:返回可迭代的元素数量;
  • + *
  • {@link Iterator}或{@link Iterable}:可迭代的元素数量;副作用:{@link Iterator}只能被迭代一次
  • + *
  • {@link Enumeration}:返回可迭代的元素数量;副作用:{@link Enumeration}只能被迭代一次
  • * * * @param obj 被计算长度的对象 diff --git a/hutool-core/src/test/java/cn/hutool/v7/core/util/ObjUtilTest.java b/hutool-core/src/test/java/cn/hutool/v7/core/util/ObjUtilTest.java index 9ca6262c6..fd26848d2 100644 --- a/hutool-core/src/test/java/cn/hutool/v7/core/util/ObjUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/v7/core/util/ObjUtilTest.java @@ -30,6 +30,9 @@ import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + /** * test for {@link ObjUtil} */ @@ -60,31 +63,31 @@ public class ObjUtilTest { a = 1; b = 1.0; - Assertions.assertFalse(ObjUtil.equals(a, b)); + assertFalse(ObjUtil.equals(a, b)); } @Test public void lengthTest(){ final int[] array = new int[]{1,2,3,4,5}; int length = ObjUtil.length(array); - Assertions.assertEquals(5, length); + assertEquals(5, length); final Map map = new HashMap<>(); map.put("a", "a1"); map.put("b", "b1"); map.put("c", "c1"); length = ObjUtil.length(map); - Assertions.assertEquals(3, length); + assertEquals(3, length); final Iterable list = ListUtil.of(1, 2, 3); - Assertions.assertEquals(3, ObjUtil.length(list)); - Assertions.assertEquals(3, ObjUtil.length(Arrays.asList(1, 2, 3).iterator())); + assertEquals(3, ObjUtil.length(list)); + assertEquals(3, ObjUtil.length(Arrays.asList(1, 2, 3).iterator())); } @Test public void containsTest(){ Assertions.assertTrue(ObjUtil.contains(new int[]{1,2,3,4,5}, 1)); - Assertions.assertFalse(ObjUtil.contains(null, 1)); + assertFalse(ObjUtil.contains(null, 1)); Assertions.assertTrue(ObjUtil.contains("123", "3")); final Map map = new HashMap<>(); map.put(1, 1); @@ -102,7 +105,7 @@ public class ObjUtilTest { @SuppressWarnings("ConstantConditions") @Test public void isNotNullTest() { - Assertions.assertFalse(ObjUtil.isNotNull(null)); + assertFalse(ObjUtil.isNotNull(null)); } @Test @@ -117,12 +120,12 @@ public class ObjUtilTest { @Test public void isNotEmptyTest() { - Assertions.assertFalse(ObjUtil.isNotEmpty(null)); - Assertions.assertFalse(ObjUtil.isNotEmpty(new int[0])); - Assertions.assertFalse(ObjUtil.isNotEmpty("")); - Assertions.assertFalse(ObjUtil.isNotEmpty(Collections.emptyList())); - Assertions.assertFalse(ObjUtil.isNotEmpty(Collections.emptyMap())); - Assertions.assertFalse(ObjUtil.isNotEmpty(Collections.emptyIterator())); + assertFalse(ObjUtil.isNotEmpty(null)); + assertFalse(ObjUtil.isNotEmpty(new int[0])); + assertFalse(ObjUtil.isNotEmpty("")); + assertFalse(ObjUtil.isNotEmpty(Collections.emptyList())); + assertFalse(ObjUtil.isNotEmpty(Collections.emptyMap())); + assertFalse(ObjUtil.isNotEmpty(Collections.emptyIterator())); } @SuppressWarnings("ConstantValue") @@ -156,7 +159,7 @@ public class ObjUtilTest { void cloneListTest() { final ArrayList list = ListUtil.of(1, 2); final ArrayList clone = ObjUtil.clone(list); - Assertions.assertEquals(list, clone); + assertEquals(list, clone); } @Test @@ -165,11 +168,11 @@ public class ObjUtilTest { final CloneableBean cloneableBean1 = new CloneableBean(1); final CloneableBean cloneableBean2 = ObjUtil.clone(cloneableBean1); - Assertions.assertEquals(cloneableBean1, cloneableBean2); + assertEquals(cloneableBean1, cloneableBean2); final SerializableBean serializableBean1 = new SerializableBean(2); final SerializableBean serializableBean2 = ObjUtil.clone(serializableBean1); - Assertions.assertEquals(serializableBean1, serializableBean2); + assertEquals(serializableBean1, serializableBean2); final Bean bean1 = new Bean(3); Assertions.assertNull(ObjUtil.clone(bean1)); @@ -180,10 +183,10 @@ public class ObjUtilTest { Assertions.assertNull(ObjUtil.clone(null)); final CloneableBean cloneableBean1 = new CloneableBean(1); - Assertions.assertEquals(cloneableBean1, ObjUtil.cloneIfPossible(cloneableBean1)); + assertEquals(cloneableBean1, ObjUtil.cloneIfPossible(cloneableBean1)); final SerializableBean serializableBean1 = new SerializableBean(2); - Assertions.assertEquals(serializableBean1, ObjUtil.cloneIfPossible(serializableBean1)); + assertEquals(serializableBean1, ObjUtil.cloneIfPossible(serializableBean1)); final Bean bean1 = new Bean(3); Assertions.assertSame(bean1, ObjUtil.cloneIfPossible(bean1)); @@ -197,7 +200,7 @@ public class ObjUtilTest { Assertions.assertNull(ObjUtil.cloneByStream(null)); Assertions.assertNull(ObjUtil.cloneByStream(new CloneableBean(1))); final SerializableBean serializableBean1 = new SerializableBean(2); - Assertions.assertEquals(serializableBean1, ObjUtil.cloneByStream(serializableBean1)); + assertEquals(serializableBean1, ObjUtil.cloneByStream(serializableBean1)); Assertions.assertNull(ObjUtil.cloneByStream(new Bean(1))); } @@ -211,26 +214,54 @@ public class ObjUtilTest { @Test public void isValidIfNumberTest() { Assertions.assertTrue(ObjUtil.isValidIfNumber(null)); - Assertions.assertFalse(ObjUtil.isValidIfNumber(Double.NEGATIVE_INFINITY)); - Assertions.assertFalse(ObjUtil.isValidIfNumber(Double.NaN)); + assertFalse(ObjUtil.isValidIfNumber(Double.NEGATIVE_INFINITY)); + assertFalse(ObjUtil.isValidIfNumber(Double.NaN)); Assertions.assertTrue(ObjUtil.isValidIfNumber(Double.MIN_VALUE)); - Assertions.assertFalse(ObjUtil.isValidIfNumber(Float.NEGATIVE_INFINITY)); - Assertions.assertFalse(ObjUtil.isValidIfNumber(Float.NaN)); + assertFalse(ObjUtil.isValidIfNumber(Float.NEGATIVE_INFINITY)); + assertFalse(ObjUtil.isValidIfNumber(Float.NaN)); Assertions.assertTrue(ObjUtil.isValidIfNumber(Float.MIN_VALUE)); } @Test public void getTypeArgumentTest() { final Bean bean = new Bean(1); - Assertions.assertEquals(Integer.class, ObjUtil.getTypeArgument(bean)); - Assertions.assertEquals(String.class, ObjUtil.getTypeArgument(bean, 1)); + assertEquals(Integer.class, ObjUtil.getTypeArgument(bean)); + assertEquals(String.class, ObjUtil.getTypeArgument(bean, 1)); } @Test public void toStringTest() { - Assertions.assertEquals("null", ConvertUtil.toStrOrNullStr(null)); - Assertions.assertEquals(Collections.emptyMap().toString(), ConvertUtil.toStrOrNullStr(Collections.emptyMap())); - Assertions.assertEquals("[1, 2]", Arrays.asList("1", "2").toString()); + assertEquals("null", ConvertUtil.toStrOrNullStr(null)); + assertEquals(Collections.emptyMap().toString(), ConvertUtil.toStrOrNullStr(Collections.emptyMap())); + assertEquals("[1, 2]", Arrays.asList("1", "2").toString()); + } + + @Test + public void testLengthConsumesIterator() { + List list = Arrays.asList("a", "b", "c"); + Iterator iterator = list.iterator(); + // 迭代器第一次调用length + int length1 = ObjUtil.length(iterator); + assertEquals(3, length1); + // 迭代器第二次调用length - 迭代器已经被消耗,返回0 + int length2 = ObjUtil.length(iterator); + assertEquals(0, length2); // 但当前实现会重新遍历,但iterator已经没有元素了 + // 尝试使用迭代器 - 已经无法使用 + assertFalse(iterator.hasNext()); + } + + @Test + public void testLengthConsumesEnumeration() { + Vector vector = new Vector<>(Arrays.asList("a", "b", "c")); + Enumeration enumeration = vector.elements(); + // 第一次调用length + int length1 = ObjUtil.length(enumeration); + assertEquals(3, length1); + // 第二次调用length - 枚举已经被消耗 + int length2 = ObjUtil.length(enumeration); + assertEquals(0, length2); + // 枚举已经无法使用 + assertFalse(enumeration.hasMoreElements()); } @RequiredArgsConstructor