0

As you can see, it's an ArrayList of objects and I need each of these objects to count their province attributes based on men and women

class Registro {
    String region;
    String province;
    String gender;
}

List<Registro> reg = new ArrayList<Registro>();
        reg.add(new Registro("China","Beigin","male"));
        reg.add(new Registro("China","Beigin","female"));
        reg.add(new Registro("China","x","male"));
        reg.add(new Registro("China","x","female"));
        reg.add(new Registro("China","x","male"));
        reg.add(new Registro("EEUU","SB","female"));
        reg.add(new Registro("EEUU","SB","female"));
        reg.add(new Registro("EEUU","CAL","male"));
        reg.add(new Registro("EEUU","CAL","male"));

The desired output

  /*

China, Beigin, 1 male, 1 female 
China,    x  , 2 male, 1 female 
EEUU,    SB  , 0 male, 2 female 
EEUU,    CAL , 2 male, 0 female */
koshy george
  • 671
  • 6
  • 24
  • You can try to write your own priorityqueue object. It will sort based on province name when offered a new "Registro", and you can override the offer method to call the parent offer, then also have a hashmap object where you add numbers to the province name to keep track of count. – Raghav Apr 19 '20 at 22:06

1 Answers1

0

A Map for each sex

One quick and dirty approach would be a pair of Map objects, for male and female each, where the key is a combination of your country and region while the value is an Integer for the count of elements found.

Map< String , Integer > females = new TreeMap<>() ;
Map< String , Integer > males = new TreeMap<>() ;

Loop your collection of Registro objects. For each Registro object, get the country and region, and concatenate. Use some arbitrary character as a delimiter, such as a pipe | (VERTICAL LINE), so you can later pull country and region apart (if need be). That string is the key in your map.

The value in the map, the Integer object, is a count of Registro objects for that country-region in that sex. See this Answer to learn about using Map::merge to increment the map’s Integer value using a method reference, Integer::sum.

String key = registro.getCountry() + "|" + registro.getRegion() ;
if( registro.getSex().equals( "female" ) )
{
    females.merge( key , 1 , Integer::sum ) ;
} 
else if( registro.getSex().equals( "male" ) )
{
    males.merge( key , 1 , Integer::sum ) ;
} 
else // defensive programming
{ 
    … handle error condition, illegal state.
}

To build your report, get a distinct set of all keys from both maps. Use a Set for this, as a set eliminates duplicates. The Set returned by Map::keySet is actually a view onto the map rather than a separate collection. So we pass that set for one sex to constructor of a new and separate set. For the other sex, we call Set::addAll. Thus we combine the two maps’ keys into a single distinct set.

We use a TreeSet to keep the keys in natural order, matching the natural order used by the TreeMap.

Set< String > keys = new TreeSet<>( females.keySet() ) ;  // Build a fresh independent set from the set returned by `Map::keySet`. 
keys.addAll( males.keySet() ) ;                           // Add in all the keys from the other map, automatically eliminating duplicates. 

To build your report, loop the keys set. For each key, call females.getKey to get back a count, and call males.getKey to get back a count. If either returns a null, report zero for that sex in that country-region.

for( String key : keys ){
    Integer countFemales = Objects.requireNonNullElse​( females.getKey( key ) , new Integer( 0 ) ) ;
    Integer countMales = Objects.requireNonNullElse​( males.getKey( key ) , new Integer( 0 ) ) ;

    String output = key + " = " + countFemales + " females, " + countMales + " males." ;
}

China|Beigin = 13 females, 7 males.

The approach described here assumes your collection of Registro objects is not being modified by another thread.

I expect there are other ways to solve your problem, likely more elegant no doubt. But this should get the job. I would use this approach myself.

By the way, here is a graphic table I made showing the attributes of various Map implementations.

Table of map implementations in Java 11, comparing their features

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154