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

时间:2009-12-07 15:07:13

标签: java list collections enums

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

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

对此最好的解决方案是什么?我不想每次都在列表中进行迭代。

8 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:2)

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

我的问题用法:

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

答案 2 :(得分:1)

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

您需要做的就是覆盖add / remove / addAll等方法并在将计数器传递给真正的列表类型之前递增计数器。关于它的最好的部分是你可以用你的新包装器装饰任何列表类型。

答案 3 :(得分:1)

至少,实用方法如:

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

让您简明扼要地参考代码中其他地方的PLAYSTATION数量。或者,如果您知道列表不太可能更改,那么构建Map<Toy, Integer>可以让您为所有项目建立一次计数。

答案 4 :(得分:1)

如果您不希望每次都要遍历整个集合,另一种方法是编写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;
    }

}

答案 5 :(得分:0)

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

答案 6 :(得分:0)

HashBag(Bozho)似乎是你最好的选择。但更常见的是Googles Collections 2具有适当的谓词:

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

答案 7 :(得分:0)

除了所有这些解决方案(我对Collections.Frequency调用有一个弱点),我建议你看看google collections,特别是[Collections2.transform] [2],这可能会给你现场观看物品。

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