我有一个java.util.ArrayList<Item>
和一个Item
对象。
现在,我想获得Item
存储在arraylist中的次数。
我知道我可以进行arrayList.contains()
检查但它返回true,无论它是否包含一个或多个Item
s。
Q1。如何找到项目存储在列表中的时间?
Q2。此外,如果列表包含多个项目,那么如何确定其他项目的索引,因为arrayList.indexOf(item)
每次只返回第一个项目的索引?
答案 0 :(得分:22)
您可以使用Collections
类:
public static int frequency(Collection<?> c, Object o)
返回指定集合中等于指定对象的元素数。更正式地,返回集合中元素e的数量,使得(o == null?e == null:o.equals(e))。
如果您需要多次计算长列表的出现次数,我建议您使用HashMap
存储计数器并在将新项目插入列表时更新它们。这样可以避免计算任何类型的计数器..但当然你不会有指数。
HashMap<Item, Integer> counters = new HashMap<Item, Integer>(5000);
ArrayList<Item> items = new ArrayList<Item>(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
数据结构
定义一个集合,该集合计算对象在集合中出现的次数。
正是你需要的......
答案 1 :(得分:5)
这很容易手工完成。
public int countNumberEqual(ArrayList<Item> itemList, Item itemToCheck) {
int count = 0;
for (Item i : itemList) {
if (i.equals(itemToCheck)) {
count++;
}
}
return count;
}
请注意,如果您未在equals
类中重写Item
,则此方法将使用对象标识(因为这是Object.equals()
的实现)。
修改:关于您的第二个问题(请尝试将帖子限制为每个问题),您也可以手动执行此操作。
public List<Integer> indices(ArrayList<Item> items, Item itemToCheck) {
ArrayList<Integer> ret = new ArrayList<Integer>();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).equals(itemToCheck)) {
ret.add(i);
}
}
return ret;
}
答案 2 :(得分:0)
正如其他受访者已经说过的那样,如果您坚定地将项目存储在无序的ArrayList中,那么计算项目将花费O(n)时间,其中n是列表中的项目数。在SO,我们提供建议,但我们不做魔术!
正如我刚才暗示的那样,如果列表的搜索次数远远超过修改后的列表,那么保持列表排序可能是有意义的。如果您的列表已排序,那么您可以在O(log n)时间内找到您的项目,这样会快得多;如果您的hashcode
实施与equals
相符,那么所有相同的项目就会相互靠近。
另一种可能性是并行创建和维护两个数据结构。您可以使用包含项目作为键的HashMap
及其作为值的计数。您有义务在列表更改时更新此第二个结构,但项目计数查找将为o(1)。
答案 3 :(得分:0)
我可能错了,但在我看来,您实际想要的数据结构可能是Multiset(来自google-collections / guava),而不是List
。与Set
不同,它允许多个,但实际上并不关心顺序。鉴于此,它有一个int count(Object element)
方法,可以完全满足您的需求。由于它不是一个列表,并且具有HashMap
支持的实现,因此获得计数效率要高得多。
答案 4 :(得分:0)
感谢您提出的所有建议。但是这下面的代码非常有用,因为我们没有任何带有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
答案 5 :(得分:0)
我知道这是一篇老文章,但是由于我没有看到哈希图解决方案,因此我决定为将来需要它的任何人在哈希图上添加一个伪代码。假定arraylist和Float数据类型。
Map<Float,Float> hm = new HashMap<>();
for(float k : Arralistentry) {
Float j = hm.get(k);
hm.put(k,(j==null ? 1 : j+1));
}
for(Map.Entry<Float, Float> value : hm.entrySet()) {
System.out.println("\n" +value.getKey()+" occurs : "+value.getValue()+" times");
}