计算ArrayList中项的出现次数

时间:2010-04-15 16:41:51

标签: java list arraylist

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

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

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

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

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

6 个答案:

答案 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

http://binodsuman.blogspot.com

答案 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");
  }