计算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