Home > OS >  How to create a map with an attribute as a key and a maximum value as a value
How to create a map with an attribute as a key and a maximum value as a value

Time:05-22

So, In college we are working with csv files and streams. Right now I am doing some homework but I've been stuck in this exercise for some days now. I have a csv file with some data about accidents (like the accident severity, the number of victims and so) and I have a function that reads that data and converts it to a list of Accident objects (which has a property for each type of data the csv has). I have saved that list in an object and I can call the list with getAccidents(). Right now, I have to make a function that does what the title says. I have thought that the map keys could be the severity (which is an enumerate with values slight, serious and fatal) and the values could be the max number of victims (the number of victims is an Integer) of every accident with that same severity. For example, the map output could be: SLIGHT=1, SERIOUS=3, FATAL=5. I have tried using the Collections, Collectors and Comparator libraries but I can't find any way to divide all the Accidents in each severity value, get the maximum number of victims for each and then save both values in a Map<Severity, Integer> map. The function right now starts this way: public Map<Severity, Integer> getMaxVictimsPerSeverity() { return getAccidents().stream().collect(Collectors.toMap(Accident::getSeverity, ...)) and then I have tried a lot of things but I can't find any way to make it return what I want. I am still a newby and I don't understand a lot of things yet so ask if I have forgotten anything.

CodePudding user response:

You are trying to group by Severity and count the number of Accidents in each group.

Map<Severity, Long> counted = list.stream()
            .collect(Collectors.groupingBy(Accident::getSeverity, Collectors.counting()));

This should help you achieve what you are looking for.

Here is a working example:

import java.util.*;
import java.util.stream.*;

public class Test {
    
    public static void main(String args[]) {
      Accident a1 = new Accident(Severity.SLIGHT);
      Accident a2 = new Accident(Severity.SERIOUS);
      Accident a3 = new Accident(Severity.SLIGHT);
      Accident a4 = new Accident(Severity.FATAL);
      Accident a5 = new Accident(Severity.FATAL);
      
      List<Accident> list= new ArrayList<>();
      list.add(a1);
      list.add(a2);
      list.add(a3);
      list.add(a4);
      list.add(a5);
      
      Map<Severity, Long> counted = list.stream()
            .collect(Collectors.groupingBy(Accident::getSeverity, Collectors.counting()));

      System.out.println(counted);
    }
    
    static class Accident{
        Severity severtity;
        Accident(Severity s){
            this.severtity = s;
        }

        public Severity getSeverity(){
            return severtity;
        }
    }

    static enum Severity{
        SLIGHT, SERIOUS, FATAL;
    }
}

The Result: {FATAL=2, SLIGHT=2, SERIOUS=1}

CodePudding user response:

Provide a value extractor to get the victims of each accident, and a reducer to keep the highest number of victims.

return getAccidents().stream()
    .collect(Collectors.toMap(Accident::getSeverity, Accident::getVictims, Integer::max));
  • Related