计算ArrayList中项的出现次数

我有一个java.util.ArrayList和一个Item对象。

现在,我想获得Item存储在arraylist中的次数。

我知道我可以执行arrayList.contains()检查,但它返回true,无论它是否包含一个或多个Item

Q1。 如何找到项目存储在列表中的时间?

Q2。 此外,如果列表包含多个Item,那么如何确定其他Items的索引,因为arrayList.indexOf(item)每次只返回第一个Item的索引?

您可以使用Collections类:

 public static int frequency(Collection c, Object o) 

返回指定集合中等于指定对象的元素数。 更正式地,返回集合中元素e的数量,使得(o == null?e == null:o.equals(e))。

如果您需要多次计算长列表的出现次数,我建议您使用HashMap存储计数器并在将新项目插入列表时更新它们。 这将避免计算任何类型的计数器..但当然你不会有索引。

 HashMap counters = new HashMap(5000); ArrayList items = new ArrayList(5000); void insert(Item newEl) { if (counters.contains(newEl)) counters.put(newEl, counters.get(newEl)+1); else counters.put(newEl, 1); items.add(newEl); } 

最后的提示:您可以使用其他集合框架(如Apache Collections )并使用描述为的Bag结构

定义一个集合,该集合计算对象在集合中出现的次数。

所以你需要的……

这很容易手工完成。

 public int countNumberEqual(ArrayList itemList, Item itemToCheck) { int count = 0; for (Item i : itemList) { if (i.equals(itemToCheck)) { count++; } } return count; } 

请记住,如果不在Item类中重写equals ,则此方法将使用对象标识(因为这是Object.equals()的实现)。

编辑 :关于你的第二个问题(请尝试将post限制为每个问题),你也可以手动完成。

 public List indices(ArrayList items, Item itemToCheck) { ArrayList ret = new ArrayList(); for (int i = 0; i < items.size(); i++) { if (items.get(i).equals(itemToCheck)) { ret.add(i); } } return ret; } 

正如其他受访者已经说过的那样,如果您坚定地将项目存储在无序的ArrayList中,那么计算项目将花费O(n)时间,其中n是列表中的项目数。 在SO,我们提供建议,但我们不做魔术!

正如我刚才所暗示的那样,如果列表的搜索次数远远超过修改后的列表,那么保持列表排序可能是有意义的。 如果您的列表已排序,那么您可以在O(log n)时间内找到您的项目,这样会快得多; 如果您的hashcode实现与您的equals ,那么所有相同的项目将彼此相邻。

另一种可能性是并行创建和维护两个数据结构。 您可以使用包含项目作为键的HashMap及其计数值。 您有义务在列表更改时更新此第二个结构,但项目计数查找将为o(1)。

我可能是错的,但在我看来,你真正想要的数据结构可能是Multiset (来自google-collections / guava )而不是List 。 与Set不同,它允许倍数,但实际上并不关心顺序。 鉴于此,它有一个int count(Object element)方法,它可以完全满足您的需要。 由于它不是一个列表并且具有由HashMap支持的实现,因此获得计数效率要高得多。

谢谢你的好建议。 但是这下面的代码非常有用,因为我们没有任何带有List的搜索方法可以给出出现次数。

 void insert(Item newEl) { if (counters.contains(newEl)) counters.put(newEl, counters.get(newEl)+1); else counters.put(newEl, 1); items.add(newEl); } 

谢谢杰克。 好发布。

谢谢,

Binod Suman

http://binodsuman.blogspot.com