diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java index de59ce0dd..d2fbb372c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java @@ -502,14 +502,16 @@ public class CollUtil { } /** - * 集合1中是否包含集合2中所有的元素,即集合2是否为集合1的子集, 不考虑元素的个数
- * 空集是所有集合的子集
+ * 集合1中是否包含集合2中所有的元素。
+ * 当集合1和集合2都为空时,返回{@code true} + * 当集合2为空时,返回{@code true} * * @param coll1 集合1 * @param coll2 集合2 * @return 集合1中是否包含集合2中所有的元素 * @since 4.5.12 */ + @SuppressWarnings("SuspiciousMethodCalls") public static boolean containsAll(final Collection coll1, final Collection coll2) { if (isEmpty(coll1)) { return isEmpty(coll2); @@ -519,12 +521,35 @@ public class CollUtil { return true; } - if (coll1.size() < coll2.size()) { - return false; + // Set直接判定 + if(coll1 instanceof Set){ + return coll1.containsAll(coll2); } - //noinspection SuspiciousMethodCalls - return coll1.containsAll(coll2); + // 参考Apache commons collection4 + // 将时间复杂度降低到O(n + m) + final Iterator it = coll1.iterator(); + final Set elementsAlreadySeen = new HashSet<>(coll1.size(), 1); + for (final Object nextElement : coll2) { + if (elementsAlreadySeen.contains(nextElement)) { + continue; + } + + boolean foundCurrentElement = false; + while (it.hasNext()) { + final Object p = it.next(); + elementsAlreadySeen.add(p); + if (Objects.equals(nextElement, p)) { + foundCurrentElement = true; + break; + } + } + + if (!foundCurrentElement) { + return false; + } + } + return true; } /** diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java index e911c5d1c..7cde05dd5 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java @@ -408,7 +408,7 @@ public class CollUtilTest { public void groupTest() { final List list = ListUtil.of("1", "2", "3", "4", "5", "6"); final List> group = CollUtil.group(list, null); - Assertions.assertTrue(group.size() > 0); + Assertions.assertFalse(group.isEmpty()); final List> group2 = CollUtil.group(list, t -> { // 按照奇数偶数分类 @@ -1266,4 +1266,20 @@ public class CollUtilTest { Assertions.assertArrayEquals(new String[]{"a", "b", "c", null, "d", "e", "f", "g", "h", "i", "j", "k", "l"}, flat.toArray()); } + @Test + void issueI8Z2Q4Test() { + final ArrayList coll1 = new ArrayList<>(); + coll1.add("1"); + coll1.add("2"); + coll1.add("3"); + coll1.add("4"); + final ArrayList coll2 = new ArrayList<>(); + coll2.add("1"); + coll2.add("1"); + coll2.add("1"); + coll2.add("1"); + coll2.add("1"); + + Assertions.assertTrue(CollUtil.containsAll(coll1, coll2)); + } }