关于Java Set.containsAll方法对空列表返回true的疑问
关于AbstractCollection中containsAll方法的行为疑问
AbstractCollection类中的containsAll方法实现如下:
public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; }
这个方法没有对传入的空集合c做特殊校验,当c是空集合时,方法会直接返回true。
下面的测试用例执行失败:
@Test public void testContainsAllOfHashSet() { List<String> reasons = new LinkedList<>(); Set<String> allReasons = new HashSet<>(); allReasons.add("Java"); Assert.assertFalse(allReasons.containsAll(reasons)); }
失败原因是当reasons为空列表时,containsAll返回了true,导致断言不成立。
你认为allReasons包含至少一个元素且没有空元素,这个测试用例应该通过,想确认自己的理解是否有误——你的理解确实存在偏差。
containsAll的核心语义是:调用该方法的集合,必须包含传入集合中的每一个元素。当传入的集合是空集合时,因为不存在任何需要被包含的元素,这个条件是天然成立的,返回true完全符合Java集合框架的设计规范。
从逻辑角度看,"空集合中的所有元素都在当前集合内"是一个恒真命题——因为找不到任何一个空集合里的元素不在当前集合中,所以这个判断必然为真。你的测试用例的断言逻辑是错误的,正确的断言应该是Assert.assertTrue(allReasons.containsAll(reasons))。
内容的提问来源于stack exchange,提问作者Kryptix
相关产品推荐
相关产品推荐

