如何用枚举汇总出现次数>>

问题描述 投票:0回答:2

我有一个ScenarioGenerator类来生成Scenario。在Audit类中,我设置了函数来决定要生成多少方案,并希望打印出每种枚举类型(在这种情况下为Gender)的出现。

我已经提到Counting an Occurrence in an Array (Java)

我使用了频率方法来计算发生的次数,但是当生成许多场景时,我不知道如何汇总数据。我尝试过的是:

  1. 生成方案并将每个方案添加到ArrayList中
  2. 对于每种情况,我都获得了乘客ArrayList,并将其属性保存在不同的集合中。
  3. 对于每个集合,请打印出其值和计数。
  4. 我可以这样简单地做:

    int maleCount = Collections.frequency(genderCollection, Gender.MALE);
    System.out.println(Gender.MALE.toString().toLowerCase() + ":" +maleCount);
    

但是,如果我有更多的枚举和属性,则此方法将变得冗长且效率低下。有什么办法可以解决?

这是我的Audit课程的一部分:

public class Audit {

private Scenario scenario = new Scenario();
private ScenarioGenerator scenarioGenerator = new ScenarioGenerator();
private Person person = new Person();

private String auditType;
private int nubmerOfSimulation;

public enum Gender {
    MALE, FEMALE, UNKNOWN;
}

public Audit() {

}

// create a specific number of random scenarios
// the concept similar to gamePlayed and gameWon in the last project
public void run(int runs) {
    this.nubmerOfSimulation = runs;
    ArrayList<Scenario> scenarios = new ArrayList<Scenario>();//create a arrayList to store each scenario

    for (int i = 0; i < runs; i++) {
        Scenario singleScenario = scenarioGenerator.generate();
        scenarios.add(singleScenario); // save each scenario into a scenario arrayList
    }
    survialCalculator(scenarios);        
}

public int survialCalculator(ArrayList<Scenario> scenarios) {
    //person attribute arrayList
    ArrayList<Gender> genderCollection = new ArrayList<Gender>();

    for (Scenario scenario : scenarios) { // for each scenario, getting its passengers and pedestrians
        ArrayList<Character> passengers =  scenario.getPassengers();
        for (Character passenger : passengers) {
            if (passenger instanceof Person) {
                Gender gender = ((Person) passenger).getGender();
                //System.out.println(gender);
                genderCollection.add(gender);    
        }
    }

    //try to print out the elements in the collection and its frequency, but failed
    for(Gender genderElement : genderCollection) {
        int genderCount = Collections.frequency(genderCollection, genderElement);
        System.out.println(genderElement.toString().toLowerCase()+ ":" + genderCount);
    }

    return 1;

}

这里是我的ScenarioGenerator的一部分:

public class ScenarioGenerator {


private Person person = new Person();
private Random random = new Random();   

private int passengerCountMinimum;
private int passengerCountMaximum;

private int pedestrianCountMininum;
private int pedestrianCountMaximum;

private ArrayList<Character> passengers = new ArrayList<Character>();
private ArrayList<Character> pedestrians = new ArrayList<Character>();

public Person getRandomPerson() {
    //need age, gender, bodyType, profession, pregnancy
    int age = random.nextInt(100);
    int profession = random.nextInt(person.getProfessionEnumLength());
    int gender = random.nextInt(person.getGenderEnumLength());
    int bodyType = random.nextInt(person.getBodyTypeEnumLength());
    int pregnancy = random.nextInt(2);

    Person people = new Person(age, 
                               Profession.values()[profession], 
                               Gender.values()[gender],
                               BodyType.values()[bodyType], 
                               pregnancy == 1 ? true : false);
    return people;
}

public Animal getRandomAnimal() {
    //species, isPet
    int age = random.nextInt(100);
    int gender = random.nextInt(person.getGenderEnumLength());
    int bodyType = random.nextInt(person.getBodyTypeEnumLength());
    boolean isPet = random.nextBoolean();


    String [] species = {"cat", "dog"};
    int idx = random.nextInt(species.length);
    String pickSpecies = species[idx];


    Animal creature = new Animal(age, Gender.values()[gender], BodyType.values()[bodyType] , pickSpecies); 
    creature.setIsPet(isPet);

    return creature;       
}
//getters and setter of min and max numbers of passengers and pedestrians
public Scenario generate() {

    //random number of passengers and pedestrians with random characteristics
    //randomly red light or green light
    //random condition "You" in the car
    //abide by the minimum and maximum counts from above setters

    //get random numbers abide by the setters
    int numberOfPassengers = ThreadLocalRandom.current().nextInt(getPassengerCountMin(), getPassengerCountMax()+1);
    int numberOfPedestrains =ThreadLocalRandom.current().nextInt(getPedestrianCountMin(), getPedestrianCountMax()+1);

    boolean legalCrossing = random.nextBoolean();

    //generate the number from the total numbers of passenger and pedestrians
    int numberOfPersonPassenger = ThreadLocalRandom.current().nextInt(0, numberOfPassengers+1);
    int numberOfAnimalPassenger = numberOfPassengers - numberOfPersonPassenger;

    int numberOfPersonPedestrian = ThreadLocalRandom.current().nextInt(0, numberOfPedestrains+1);
    int numberOfAnimalPedestrian = numberOfPedestrains - numberOfPersonPedestrian;

    //generate the number of person passengers
    for (int i = numberOfPersonPassenger; i > 0; i--) {
        Person person = getRandomPerson();
        passengers.add(person);
    }

    //remaining of the number of passengers should be animals
    //no matter it is pet of not
    for (int i = numberOfAnimalPassenger; i > 0; i--) {
        Animal animal = getRandomAnimal();
        passengers.add(animal);
    }

    for (int i = numberOfPersonPedestrian; i > 0; i--) {
        Person person = getRandomPerson();
        pedestrians.add(person);
    }

    for (int i =numberOfAnimalPedestrian; i > 0; i--) {
        Animal animal = getRandomAnimal();
        pedestrians.add(animal);
    }
    Scenario scenario = new Scenario(passengers, pedestrians, legalCrossing);

 return scenario;

}

这是我的Scenario课程的一部分:

public class Scenario {
private Random random;

private ArrayList<Character> passenagers = new ArrayList<Character>();
private ArrayList<Character> pedestrians = new ArrayList<Character>();

private boolean legalCrossing;


public Scenario() {

}

public Scenario(ArrayList<Character> passengers, ArrayList<Character> pedestrians, boolean isLegalCrossing) {
    this.passenagers = passengers;
    this.pedestrians = pedestrians;
    this.legalCrossing = isLegalCrossing;
}
//getters and setters

主要类是调用方法:

public static void main(String[] args) throws Exception {

    ethicalEngine.generate();

}
public void generate() { 
    Audit audit = new Audit();
    audit.run(5); 
}

我有一个ScenarioGenerator类来生成场景。在Audit类中,我设置函数来决定要生成多少个场景,并希望打印出每个枚举的出现...

java object arraylist enums find-occurrences
2个回答
1
投票

您可以在groupingBy上使用List<Gender>流操作来获取带有计数的所有性别类型的图。

Map<Gender, Long> counted = genderCollection.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

2
投票

您可能考虑使用Guava Multiset。如状态here所示,当您有更多属性要计数时,此数据结构会更有效,因为对数字的访问位于most of the time in O(1)

© www.soinside.com 2019 - 2024. All rights reserved.