我有一个ScenarioGenerator
类来生成Scenario
。在Audit
类中,我设置了函数来决定要生成多少方案,并希望打印出每种枚举类型(在这种情况下为Gender
)的出现。
我已经提到Counting an Occurrence in an Array (Java)
我使用了频率方法来计算发生的次数,但是当生成许多场景时,我不知道如何汇总数据。我尝试过的是:
我可以这样简单地做:
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类中,我设置函数来决定要生成多少个场景,并希望打印出每个枚举的出现...
您可以在groupingBy
上使用List<Gender>
流操作来获取带有计数的所有性别类型的图。
Map<Gender, Long> counted = genderCollection.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
您可能考虑使用Guava Multiset。如状态here所示,当您有更多属性要计数时,此数据结构会更有效,因为对数字的访问位于most of the time in O(1)。