Java - 检索列表中类型的数量

发布于 2024-08-13 23:54:20 字数 263 浏览 1 评论 0 原文

我有一个清单。该列表可以包含相同枚举类型的多个项目。

假设我有一个枚举:TOY,其值:BALLDOLLPLAYSTATION。我想知道类型为 TOY 的列表中有多少个 PLAYSTATION 项目。 (即 List 玩具)

对此最好的解决方案是什么?我不想每次都重复列表。

I have a list. The list can contain multiple items of the same enum type.

Lets say i have an enum : TOY which has values: BALL, DOLL, PLAYSTATION. I want to know how many PLAYSTATION items are in a list with the type TOY. (ie, List<Toy> toys)

What is the best possible solution for this? I don't want to keep iterating through the list everytime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

我做我的改变 2024-08-20 23:54:20

您可以使用 Apache commons-collections' HashBag。它有一个适合您的 getCount(Object) 方法。

You can use Apache commons-collections' HashBag. It has a getCount(Object) method which will suit you.

独留℉清风醉 2024-08-20 23:54:20

java.util.Collections 有一个名为 Frequency(Collection c, Object type) 的方法。

我的问题中的用法:

int amountOfPlayStations = Collections.Frequency(toys, TOY.PLAYSTATION);

java.util.Collections has a method called frequency(Collection c, Object type).

Usage in my question:

int amountOfPlayStations = Collections.frequency(toys, TOY.PLAYSTATION);
岁月如刀 2024-08-20 23:54:20

为什么不为您正在使用的列表类型创建一个装饰器,该装饰器存储内部添加/删除的每个枚举类型的计数列表。这样您就可以将其用作普通列表,但还可以添加一些额外的功能来查询当前包含的类型的数量。

您需要做的就是重写 add/remove/addAll 等方法并增加计数器,然后再将其传递给真正的列表类型。最好的部分是您可以使用新包装来装饰任何列表类型。

Why don't you create a decorator for the type of list you're using which stores a list of counts for each enum type have been added/removed internally. That way you could use it as a normal list but also add some extra functionality for querying how many of which type are currently contained.

All you'd need to do would be to override the add/remove/addAll etc methods and increment your counters before passing it on to the real list type. The best part about it would be that you could decorate any list type with your new wrapper.

纸伞微斜 2024-08-20 23:54:20

至少,像这样的实用方法

public int count(List<Toy> haystack, Toy needle) {
    int result;
    for (Toy t : haystack) {
        if (t == needle) {
           result++;
        }
    }
    return result;
}

可以让您从代码中的其他地方简洁地引用 PLAYSTATION 的数量。或者,如果您知道列表不太可能更改,则构建 Map 可以让您一次性计算所有项目的计数。

At the very least, a utility method like:

public int count(List<Toy> haystack, Toy needle) {
    int result;
    for (Toy t : haystack) {
        if (t == needle) {
           result++;
        }
    }
    return result;
}

Would let you concisely refer to the number of PLAYSTATIONs from elsewhere in the code. Alternatively if you knew the list was unlikely to change, building a Map<Toy, Integer> would let you build up the counts for all items once.

自我难过 2024-08-20 23:54:20

如果您不想每次都迭代整个集合,另一种选择是编写 ForwardingList 实现。与 HashBag 建议相比,这种方法的主要优点是:

  • 它支持泛型
  • 它实现了 List 接口,因此您可以将其传递给任何需要 List 的方法

但是,这种方法有一个缺点,因为您必须编写一些管道代码以使其启动并运行。

下面是一个简单的示例,说明了如何做到这一点。请注意,如果您这样做,您应该覆盖所有从列表中添加/删除的方法,否则您可能会处于不一致的状态:

import com.google.common.collect.ForwardingList;


public class CountingList<E> extends ForwardingList<E> {

    private List<E> backingList = new LinkedList<E>();
    private Map<E, Integer> countMap = new HashMap<E, Integer>();

    @Override
    protected List<E> delegate() {
        return backingList;
    }

    @Override
    public boolean add(E element) {
        backingList.add(element);
        if(countMap.containsKey(element)) {
            countMap.put(element, countMap.get(element) + 1);
        } else {
            countMap.put(element, 1);
        }
        return true;
    }

    public int getCount(E element) {
        Integer count = countMap.get(element);
        return count != null ? count.intValue() : 0;
    }

}

If you don't want to have to iterate over the entire collection each time, another alternative would be to write a ForwardingList implementation. The main benefits of this over the HashBag suggestion are:

  • it supports generics
  • it implements the List interface, so you can pass it to any method that expects a List

There is a downside to this approach however, in that you have to write a bit of plumbing code to get it up and running.

Below is a quick example of how you could do it. Note that if you do this you should override all methods that add/delete from the list, otherwise you may end up in an inconsistent state:

import com.google.common.collect.ForwardingList;


public class CountingList<E> extends ForwardingList<E> {

    private List<E> backingList = new LinkedList<E>();
    private Map<E, Integer> countMap = new HashMap<E, Integer>();

    @Override
    protected List<E> delegate() {
        return backingList;
    }

    @Override
    public boolean add(E element) {
        backingList.add(element);
        if(countMap.containsKey(element)) {
            countMap.put(element, countMap.get(element) + 1);
        } else {
            countMap.put(element, 1);
        }
        return true;
    }

    public int getCount(E element) {
        Integer count = countMap.get(element);
        return count != null ? count.intValue() : 0;
    }

}
各自安好 2024-08-20 23:54:20

扩展 java.util.List 方法并重写所有 mutator 方法,即用于添加或删除元素的方法以及用于清除列表的方法。添加对私有 java.util.Map 的引用,它将保存每种类型的项目数。添加访问器方法,该方法将返回每种类型的当前元素数。

Extend java.util.List method and override all mutator methods, i.e. the ones that are used for add or delete elements and also ones used to clear the list. Add a reference to a private java.util.Map which will hold the number of items per type. Add accessor methods which will return current number of elements per type.

星星的軌跡 2024-08-20 23:54:20

HashBag(Bozho 开发)似乎是您最好的选择。但更一般的是 Googles Collections 2 具有适当的谓词:

List<Toy> toys;
List<Toy> playstations = Collections2.filter( toys, new Predicate() {
  boolean apply(TOY toy){
    return toy == TOY.PLAYSTATION;
  }
});

The HashBag (by Bozho) seems to be your best bet. But a bit more general would be Googles Collections 2 with an appropriate Predicate:

List<Toy> toys;
List<Toy> playstations = Collections2.filter( toys, new Predicate() {
  boolean apply(TOY toy){
    return toy == TOY.PLAYSTATION;
  }
});
清风疏影 2024-08-20 23:54:20

除了所有这些解决方案(我对 Collections.Frequency 调用有弱点)之外,我建议您查看 Google 收藏集,特别是 [Collections2.transform][2],它可以让您实时查看项目。

[2]: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Collections2.html#transform(java.util.Collection, com.google.公共.基础.函数)

Besides all those solutions (I have a weakness for the Collections.Frequency call), i would recommend you to take a look at google collections, and particularly to [Collections2.transform][2], which could give you a live view on items.

[2]: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Collections2.html#transform(java.util.Collection, com.google.common.base.Function)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文