[英]How to aggregate the occurrence with enum
我有一个ScenarioGenerator
class 来生成Scenario
。 在Audit
class 中,我设置了 function 来决定要生成多少个场景,并想打印出每个枚举类型的出现(在这种情况下为Gender
)。
我是用频率法统计发生的,但是当产生的场景很多的时候,不知道怎么汇总数据。 我试过的是:
我可以简单地这样做:
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.