简体   繁体   中英

Java: Convert List<Object> to Map<String, List<String>>

I am currently getting data from database like so:

Model---Year
aaaaa---2010
aaaaa---2011
aaaaa---2012
bbbbb---2010
bbbbb---2011

I am getting this data through SQL statement, getJdbcTemplate, and ResultSet. Then storing it in a list of value object:

List<ModelAndYear> modelYearList = new ArrayList<ModelAndYear>();

My ModelAndYear class is this:

public class ModelAndYear{
   private String model;
   private String year;

   public String getModel() {
       return model;
   }
   public void setModel(String model) {
       this.model= model;
   }
   public String getYear() {
       return year;
   }
   public void setYear(String year) {
       this.year= year;
   }

How do I take the populated modelYearList who's data will be in the format of:

aaaaa,2010
aaaaa,2011
aaaaa,2012
bbbbb,2010
bbbbb,2011

and sort it into the format of

Map<String, List<String>> 

so data will be in the format of:

aaaaa,<2010,2011,2012>
bbbbb,<2010,2011>

I do not have an idea where to start.

I have:

Map<String, List<String>> newModelYearList = new HashMap<String, List<String>>();
        for(int i=0; i < modelYearList.size(), i++){
           //sorting will occur here i think?     
           //how do i program the action of getting model from list 1 and checking if it exists in list 2?
        }

As long as you have Java 8 you can do this in a single pass using streams.

What you're essentially trying to do is a groupBy function, but also applying a map on top of that. The following is what you're looking for (lots of indents added for clarity):

Map<String, List<String>> yearsByModel = 
    modelYearList
        .stream()
        .collect(
            Collectors.groupingBy(
                may -> may.getModel(),        
                Collectors.mapping(may -> may.getYear(), Collectors.toList())));

I dont want to just give the code, you should try to do it sourself.

Here is what you should do:

  1. create a new map with a string and the list, just like you want it, eg call it result

  2. loop through every element in your modelYearList

  3. get the module and check if the result map already contains the key with the same module string

  4. if so, get the list stored with the module, and add the year

  5. if not, create a new list of type string and add the year, and store it in result with the module name

Note: i will use HashSet and HashMap, but you can use List and Map too if you want

HashSet<ModelAndYear> myl = new HashSet<>();
//Add all the ModelAndYear classes that you have
HashMap<String, HashSet<String>> result = new HashMap<>();
for(ModelAndYear m : myl) //loop through every element in myl; this loop only works for lists, but makes it easier than loop with a counter in loop counting to the size of the list
    String model = myl.getModel(); //get the model
    if(result.containsKey(model)){ //did we already put a list in the result map for the model?
    result.get(model).add(m.getYear()) //add the year to the existing list in result map for the model
}else{
HashSet<String> newList = new HashSet<String>(); //create new list
newList.add(m.getYear()); //add the year
result.put(model, newList); //Store the list in the results
}

This code give you the result map as per the requirement:

Map<String, List<String>> resultMap = 
                modelYearList
                    .stream()
                    .collect(
                        Collectors.groupingBy(
                                ModelAndYear::getModel,        
                            Collectors.mapping(ModelAndYear::getYear, Collectors.toList())));
        
        resultMap.forEach((k, v) -> System.out.println(k +" : "+ v.toString()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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