从Java列表中打印重复项

时间:2014-10-16 12:54:02

标签: java collections

真正基本的问题:

我有一些项目被添加到某个集合中(我还不介意哪些)我想要一个以组的形式打印项目的方法,例如。

public enum Animal{
COW("cow"), PIG("pig"), SHEEP("sheep");

private String itemName;

public String toString() {
    return itemName;
}
}

public class Farm {

private ArrayList<Animal> animals= new ArrayList<>();

animals.add{Animal.COW} 
animals.add{Animal.COW}
animals.add{Animal.PIG}
animals.add{Animal.COW}
animals.add{Animal.SHEEP}
animals.add{Animal.PIG}

public String animalList {

...
}

animalList输出:3 x牛,2 x猪,1 x绵羊

最好的方法是什么?地图会更好而不是列表,即每只动物的地图到这种动物的数量吗?但随后可能很难在系列中添加新动物。

7 个答案:

答案 0 :(得分:1)

HashMap是更好的选择,但请将Animal用作key

    HashMap<Animal, Integer> animalHashMap=new HashMap<Animal, Integer>();
    animalHashMap.put(Animal.COW, 3);
    animalHashMap.put(Animal.SHEEP, 10);
    animalHashMap.put(Animal.PIG, 2);

答案 1 :(得分:0)

您可以使用Multiset(Bag),例如来自番石榴集合:Multiset

你只需添加元素(动物),就可以查询每只动物在集合中的次数。

用法:

    Multiset<String> animals = HashMultiset.create();
    animals.add("cow");
    animals.add("cow");
    animals.add("cow");
    animals.add("pig");
    animals.add("pig");
    animals.add("sheep");

    for (String a : animals)
        System.out.println(animals.count(a) + "x " + a);

答案 2 :(得分:0)

这取决于你想做什么

ArrayList的想法是保持物品的顺序。然后,如果它是一个要求,那么你应该继续使用它并使用另一种算法来计算它们。

但是如果你不想要任何这些细节,你可以使用类似MultiMap(不是本机java)的东西。或者你可以创建自己的一个。

正如你在标题中指出的那样,我会做的是Map<Object,Integer>并且我检查地图是否包含对象,然后我增加整数值。然后我终于可以得到答案了。 (如@TAsk的代码所示)

答案 3 :(得分:0)

使用Java 8,您可以对动物进行流式处理并计算它们:

Map<Animal, Long> summary = animals.stream().collect(groupingBy(a -> a, counting()));

需要以下导入:

import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;

答案 4 :(得分:0)

根据您的问题,您不需要跟踪每个元素的顺序,因此您不必使用ArrayList。 您可以将EnumMapInteger一起使用作为值:

EnumMap map = new EnumMap<Animal, Integer>();

然后,您可以检查地图中是否存在每个元素,如果存在,则增加相应的值,否则将其添加值1.

EnumMap

  

用于枚举类型键的专用Map实现。

它明显比ArrayList更有效率。除非您想要其他功能,否则不要提及。

答案 5 :(得分:0)

这是一个自包含的示例,Java 5+兼容(在Main类中)...

public static void main(String[] args) throws Exception {
    ArrayList<Animal> animals = new ArrayList<>();

    animals.add(Animal.COW);
    animals.add(Animal.COW);
    animals.add(Animal.PIG);
    animals.add(Animal.COW);
    animals.add(Animal.SHEEP);
    animals.add(Animal.PIG);

    StringBuilder sb = new StringBuilder("animals contains... \n");
    for (Animal a:Animal.values()) {
        sb
            .append(a.name())
            .append(" --> ")
            .append(
                Collections.frequency(animals, a)
            )
            .append(" instances.\n");
    }
    System.out.println(sb.toString());
}

static enum Animal {
    COW("cow"), PIG("pig"), SHEEP("sheep");

    private String itemName;

    Animal(String name) {
        itemName = name;
    }

    public String toString() {
        return itemName;
    }

}

<强>输出

animals contains... 
COW --> 3 instances.
PIG --> 2 instances.
SHEEP --> 1 instances.

注意

此处需要注意的主要事项是使用Collections.frequency来计算o == null ? e == null : o.equals(e)中相同元素(Collection)的实例。

答案 6 :(得分:0)

如果您不想使用Collections.frequency()。您可以将其存储在这样的地图中

Map< Animal,Integer> countAnimals = new HasMap< Animal,Integer>();
// Initializing all the animal count to zero
for(Animal animal: Animal.values()){
    countAnimals(animal,0);
}
// counting for all animals
for(Animal animal:myListOfAnimals){ // in you case myListOfAnimals is animals
    countAnimals.put(animal, countAnimals.get(animal)++);
}

现在countAnimals地图具有所有计数。