代码之家  ›  专栏  ›  技术社区  ›  Stefan Hendriks

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

  •  3
  • Stefan Hendriks  · 技术社区  · 15 年前

    我有一张单子。列表可以包含同一枚举类型的多个项。

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

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

    8 回复  |  直到 14 年前
        1
  •  8
  •   Bozho    15 年前

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

        2
  •  2
  •   Stefan Hendriks    15 年前

    java.util.Collections 有一个方法调用 frequency(Collection c, Object type) .

    在我的问题中的用法:

    int amountOfPlayStations = Collections.frequency(toys, TOY.PLAYSTATION);
    
        3
  •  1
  •   Benj    15 年前

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

    您需要做的就是重写add/remove/add all等方法,并在将计数器传递到实际列表类型之前增加计数器的值。最好的一点是你可以用你的新包装来装饰任何列表类型。

        4
  •  1
  •   MHarris    15 年前

    至少,实用方法如下:

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

    您可以简要地参考代码中其他地方的播放站数量。或者,如果您知道列表不太可能更改,则构建一个 Map<Toy, Integer> 会让你一次建立所有项目的计数。

        5
  •  1
  •   Jared Russell    15 年前

    如果您不想每次都迭代整个集合,另一种选择是编写一个 ForwardingList 实施。与hashbag建议相比,这项建议的主要好处是:

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

    但是,这种方法有一个缺点,那就是您必须编写一些管道代码来启动和运行它。

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

    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;
        }
    
    }
    
        6
  •  0
  •   Boris Pavlović    15 年前

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

        7
  •  0
  •   extraneon    15 年前

    哈沙包(博佐的)似乎是你最好的选择。但一般来说 Googles Collections 2 使用适当的谓词:

    List<Toy> toys;
    List<Toy> playstations = Collections2.filter( toys, new Predicate() {
      boolean apply(TOY toy){
        return toy == TOY.PLAYSTATION;
      }
    });
    
        8
  •  0
  •   Riduidel    15 年前

    除了所有这些解决方案(我有一个缺点,收集。频率呼叫),我建议你看看 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.函数)