Java 计算 ArrayList 中项目的出现次数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2647232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:19:37  来源:igfitidea点击:

Count the occurrences of items in ArrayList

javalistarraylist

提问by Yatendra Goel

I have a java.util.ArrayList<Item>and an Itemobject.

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

Now, I want to obtain the number of times the Itemis stored in the arraylist.

现在,我想获取Item存储在数组列表中的次数。

I know that I can do arrayList.contains()check but it returns true, irrespective of whether it contains one or more Items.

我知道我可以做arrayList.contains()检查,但无论它是否包含一个或多个Items ,它都会返回 true 。

Q1. How can I find the number of time the Item is stored in the list?

一季度。如何找到项目在列表中存储的次数?

Q2. Also, If the list contains more than one Item, then how can I determine the index of other Items because arrayList.indexOf(item)returns the index of only first Item every time?

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

回答by danben

This is easy to do by hand.

这很容易手动完成。

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

Keep in mind that if you don't override equalsin your Itemclass, this method will use object identity (as this is the implementation of Object.equals()).

请记住,如果你不覆盖equals在你的Item类,这种方法将使用对象标识(因为这是执行Object.equals())。

Edit: Regarding your second question (please try to limit posts to one question apiece), you can do this by hand as well.

编辑:关于您的第二个问题(请尽量将帖子限制为一个问题),您也可以手动完成。

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;
}

回答by Hyman

You can use Collectionsclass:

您可以使用Collections类:

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

Returns the number of elements in the specified collection equal to the specified object. More formally, returns the number of elements e in the collection such that (o == null ? e == null : o.equals(e)).

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

If you need to count occurencies of a long list many times I suggest you to use an HashMapto store the counters and update them while you insert new items to the list. This would avoid calculating any kind of counters.. but of course you won't have indices.

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

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);
 }

A final hint: you can use other collections framework (like Apache Collections) and use a Bagdatastructure that is described as

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

Defines a collection that counts the number of times an object appears in the collection.

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

So exactly what you need..

那么正是您所需要的..

回答by Carl Smotricz

As the other respondents have already said, if you're firmly committed to storing your items in an unordered ArrayList, then counting items will take O(n) time, where n is the number of items in the list. Here at SO, we give advice but we don't do magic!

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

As I just hinted, if the list gets searched a lot more than it's modified, it might make sense to keep it sorted. If your list is sorted then you can find your item in O(log n) time, which is a lot quicker; and if you have a hashcodeimplementation that goes well with your equals, all the identical items will be right next to each other.

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

Another possibility would be to create and maintain two data structures in parallel. You could use a HashMapcontaining your items as keys and their count as values. You'd be obligated to update this second structure any time your list changes, but item count lookups would be o(1).

另一种可能性是并行创建和维护两个数据结构。您可以使用HashMap包含您的项目作为键和它们的计数作为值。每当您的列表发生变化时,您都必须更新第二个结构,但项目计数查找将是 o(1)。

回答by ColinD

I could be wrong, but it seems to me like the data structure you actually want might be a Multiset(from google-collections/guava) rather than a List. It allows multiples, unlike Set, but doesn't actually care about the order. Given that, it has a int count(Object element)method that does exactly what you want. And since it isn't a list and has implementations backed by a HashMap, getting the count is considerably more efficient.

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

回答by Ayush Suman

Thanks for your all nice suggestion. But this below code is really very useful as we dont have any search method with List that can give number of occurance.

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

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

   items.add(newEl); 
 } 

Thanks to Hyman. Good posting.

感谢Hyman。好贴。

Thanks,

谢谢,

Binod Suman

比诺·苏曼

http://binodsuman.blogspot.com

http://binodsuman.blogspot.com

回答by OlaB

I know this is an old post, but since I did not see a hash map solution, I decided to add a pseudo code on hash-map for anyone that needs it in the future. Assuming arraylist and Float data types.

我知道这是一篇旧帖子,但由于我没有看到哈希映射解决方案,因此我决定在哈希映射上为将来需要它的任何人添加伪代码。假设 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");
  }