更新
我认为您问题最清晰的陈述在您的评论中:
是的,示例 " Example: [dog,cat,cat,bird] is a match for
containing [cat,dog] is false but containing [cat,cat,dog] is true?"
正是我想要实现的。
所以实际上,您不是在寻找“子集”,因为它们不是集合。它们可以包含重复的元素。您真正想说的是,您想查看 a1
是否包含所有 a2
的元素,并且这些元素出现的次数相同。
一种方法是计算两个列表中的所有元素的数量。我们可以使用此方法获取这样的计数:
private Map<Integer, Integer> getCounter (List<Integer> list) {
Map<Integer, Integer> counter = new HashMap<>();
for (Integer item : list) {
counter.put (item, counter.containsKey(item) ? counter.get(item) + 1 : 1);
}
return counter;
}
我们将重命名您的方法为
containsAllWithCounts()
,并使用
getCounter()
作为辅助工具。您的方法还将接受
List
对象作为其参数,而不是
ArrayList
对象:指定参数为接口而不是实现是一个好习惯,这样您就不会被绑定到使用
ArrayList
类型。
考虑到这一点,我们简单地扫描
a2
中项目的计数,并查看它们在
a1
中是否相同:
public boolean containsAllWithCounts(List<Integer> a1, List<Integer> a2) {
Map<Integer,Integer> counterA1 = getCounter(a1);
Map<Integer,Integer> counterA2 = getCounter(a2);
boolean containsAll = true;
for (Map.Entry<Integer, Integer> entry : counterA2.entrySet ()) {
Integer key = entry.getKey();
Integer count = entry.getValue();
containsAll &= counterA1.containsKey(key) && counterA1.get(key).equals(count);
if (!containsAll) break;
}
return containsAll;
}
如果您愿意的话,我可以使用Java泛型重写此代码以处理任意类型,而不仅仅是 Integer
对象。另外,所有的代码都可以使用Java 8流缩短(我最初使用了它-请参见下面的注释)。只需在评论中告诉我即可。
a1Size
的值只被计算一次(在循环之前),因此基于它的值的逻辑是无意义的。 - Scary WombatremoveAll
呢? - njzk2