代码之家  ›  专栏  ›  技术社区  ›  Amit

计算ArrayList中项目的出现次数

  •  5
  • Amit  · 技术社区  · 16 年前

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

    现在,我想得到 项目 存储在arraylist中。

    我知道我能做到 arrayList.contains() 但不管它是否包含一个或多个 项目 s。

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

    arrayList.indexOf(item) 每次只返回第一项的索引?

    5 回复  |  直到 10 年前
        1
  •  22
  •   Jack    16 年前

    你可以用 Collections 班级:

    public static int frequency(Collection<?> c, Object o)
    

    如果您需要多次计算长列表的出现次数,我建议您使用 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

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

    所以你需要的就是。。

        2
  •  5
  •   danben    16 年前

    这很容易用手做。

    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;
    }
    
        3
  •  0
  •   Carl Smotricz    16 年前

    正如其他受访者已经说过的那样,如果你坚定地致力于将你的项目存储在一个无序的数组列表中,那么计算项目将花费O(n)个时间,其中n是列表中的项目数。在这里,我们给建议,但我们不做魔术!

    正如我刚刚暗示的,如果列表被搜索的次数比修改的次数多得多,那么保持它的排序可能是有意义的。如果您的列表已排序,那么您可以在O(logn)时间内找到您的项目,这要快得多;如果您有 hashcode equals ,所有相同的项目将紧挨在一起。

    HashMap 将项目作为键包含并将其计为值。您有义务在列表更改时随时更新第二个结构,但项计数查找将是o(1)。

        4
  •  0
  •   ColinD    16 年前

    我可能错了,但在我看来,您实际需要的数据结构可能是 Multiset (来自 google-collections guava )而不是一个 List Set ,但实际上并不关心订单。鉴于此,它有一个 int count(Object element) 方法来做你想做的事。而且因为它不是一个列表,而且有一个 HashMap

        5
  •  0
  •   Ayush Suman    15 年前

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

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

    多亏了杰克。发帖不错。

    谢谢,

    比诺德苏曼

    http://binodsuman.blogspot.com

        6
  •  0
  •   OlaB    6 年前

    我知道这是一篇老文章,但由于我没有看到哈希映射解决方案,我决定在哈希映射上添加一个伪代码,以供将来需要它的人使用。假设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");
      }