繁体   English   中英

如何用枚举聚合事件

[英]How to aggregate the occurrence with enum

我有一个ScenarioGenerator class 来生成Scenario Audit class 中,我设置了 function 来决定要生成多少个场景,并想打印出每个枚举类型的出现(在这种情况下为Gender )。

我提到过在数组中计数(Java)

我是用频率法统计发生的,但是当产生的场景很多的时候,不知道怎么汇总数据。 我试过的是:

  1. 生成场景并在 ArrayList 中添加每个场景
  2. 对于每个场景,我获取乘客 ArrayList,并将其属性保存在不同的 collections 中。
  3. 对于每个集合,打印出它的值和计数。

我可以简单地这样做:

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

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

这是我的Audit class 的一部分:

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 class 的一部分:

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

class主要是调用方法:

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

    ethicalEngine.generate();

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

您可以考虑使用Guava Multiset 如此处所述,当您有更多属性要计数时,此数据结构会更有效,因为对数字的访问大部分时间都在 O(1)中。

您可以对List<Gender>使用groupingBy stream 操作来获取所有性别类型的 map 和计数。

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

并以这种方式打印

for (Map.Entry<Gender, Long> item : counted.entrySet()) {
    System.out.println(item.getKey().toString()+ ":" + item.getValue());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM