HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Check if all objects have the property value of all other objects

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
theobjectsallothervaluepropertycheckhave

Problem

I have a list of objects. These objects have a processname, amount and a date. I need every object to have all dates (if it doesnt exist add a new one with amount 0). So if I have 2 processnames: 'Inflate' and 'Deflate' and they have different dates: 'Inflate':12-01-2017 and 'Deflate': 13-01-2017. I need them to have the other object's dates.

I have the following code but it feels devious:

HashSet dates = new HashSet<>();
        HashSet processes = new HashSet<>();

        //Get all the unique values from the objects. processAmounts is the list of objects
        for (ProcessAmount processAmount : processAmounts) {
            dates.add(processAmount.getDate());
            processes.add(processAmount.getProcessName());
        }

        //Loop through processnames
        for (String s : processes) {
            //Loop through all the unique dates
            for(Date date : dates) {
                //loop through the objects we have and check if the date exists.
                boolean dateFound = false;
                for(ProcessAmount processAmount : processAmounts) {
                    if(processAmount.getProcessName() != null && processAmount.getProcessName().equals(s)) {
                        if(processAmount.getDate().equals(date)) {
                            dateFound = true;
                        }
                    }
                }

                //If the date is not found add a new object with amount 0
                if(!dateFound) {
                    processAmounts.add(new ProcessAmount(date, 0, s));
                }
            }
        }


It might be a bit unclear for some people so if you don't understand I will try to explain it another way.

Solution

From the question and the comment I'd argue that your object model needs refactoring. There should be an Action object (you might come up with a better name...) tat contains the date and both of the processes Inflate and Deflate (not having a date themselves).

However...

This is how I would approach this by avoiding to iterate processAmounts excessively

public void fixMissingProcesses(){
    Map> processesPerName = separateProcessesByName();        
    List processNames = new ArrayList<>(processesPerName.keySet());
    for(int i=1;i> processesPerName = new HasMap<>();        
    for (ProcessAmount processAmount : processAmounts) {
      if(null!=processAmount.getProcessName()){
         Map processesPerDate=  processesPerName.getOrDefault(processAmount.getProcessName(),new HashMap<>());
         processesPerDate.put(processAmount.getDate(),processAmount);
         processesPerName.put(processAmount.getProcessName(),processesPerDate)
      }
    }
    return processesPerName;
}    

private void addMissingProcesses(String sourceProcessName, String targetProcessName, Map> processesPerName);
    for(Date checkDate: processesPerName.get(sourceProcessName).keySet()){
       if(!processesPerName.get(targetProcessName).containsKey(checkDate)){
         processAmounts.add(new  ProcessAmount(checkDate, 0, targetProcessName)
       }
    }
}

Code Snippets

public void fixMissingProcesses(){
    Map<String,Map<Date,ProcessAmount>> processesPerName = separateProcessesByName();        
    List<String> processNames = new ArrayList<>(processesPerName.keySet());
    for(int i=1;i<processNames.length();i++)
      for(int j=0;j<i;j++)
         addMissingProcesses(processNames.get(i),processNames.get(j), processesPerName);
}    

private void separateProcessesByName(){
    Map<String,Map<Date,ProcessAmount>> processesPerName = new HasMap<>();        
    for (ProcessAmount processAmount : processAmounts) {
      if(null!=processAmount.getProcessName()){
         Map<Date,ProcessAmount> processesPerDate=  processesPerName.getOrDefault(processAmount.getProcessName(),new HashMap<>());
         processesPerDate.put(processAmount.getDate(),processAmount);
         processesPerName.put(processAmount.getProcessName(),processesPerDate)
      }
    }
    return processesPerName;
}    


private void addMissingProcesses(String sourceProcessName, String targetProcessName, Map<String,Map<Date,ProcessAmount>> processesPerName);
    for(Date checkDate: processesPerName.get(sourceProcessName).keySet()){
       if(!processesPerName.get(targetProcessName).containsKey(checkDate)){
         processAmounts.add(new  ProcessAmount(checkDate, 0, targetProcessName)
       }
    }
}

Context

StackExchange Code Review Q#158273, answer score: 2

Revisions (0)

No revisions yet.