更新
我觉得你的问题的最明确的声明是在您的意见之一:
是的,例子“例子:[狗,猫,猫,鸟]是 c包含[猫,狗]是假的,但包含[猫,猫,狗]是真的吗?“ 正是我想要实现的。
所以真的,你不是在寻找一个“子集”,因为这些不是集合。它们可以包含重复的元素。你真正想说的是你想看看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;
}
如果你愿意,我可以重写这段代码来处理任意类型,不仅仅是Integer
对象,使用Java泛型。此外,所有代码都可以使用Java 8流(我原来使用 - 请参阅下面的注释)缩短。请在评论中告诉我。
这两个列表中的项目的顺序很重要吗? – GuiSim
'a1Size'的值只被计算一次(在循环之前),所以基于它的值的逻辑是没有意义的 –
若要从arrayList中移除使用迭代器 –