2

I want to sort an arraylist of objects and if the state is the same, then add the value of motorThefts. I am not great at working with array lists, comparing etc so any help is appreciated. -Display each state (in alphabetical order) with the total number of car thefts. Example output:

States and car theft

AK 1898

AL 9599

AR 5377

AZ 48322

I have a class StartUp.java with ArrayList of CityCrime type

    public static ArrayList<CityCrime> crimes = new ArrayList<CityCrime>();

    /**
 * Reads the crime data for each city from file
 */
public static void readCrimeData() {
    
    File file = new File("crimeUSA.csv");

    FileReader fileReader;
    BufferedReader bufferedReader;
    String crimeInfo;
    String[] stats;

    try {
        fileReader = new FileReader(file);
        bufferedReader = new BufferedReader(fileReader);

        crimeInfo = bufferedReader.readLine();
        crimeInfo = bufferedReader.readLine();

        do {
            CityCrime crime = new CityCrime(); // Default constructor
            stats = crimeInfo.split(",");
            {
                if(stats[0] != null) {
                crime.setCity(stats[0]);
            }
            if(stats[1] != null) {
                crime.setState(stats[1]);
            }
            if(stats[2] != null) {
                if(Integer.parseInt(stats[2]) >=0) {
                    crime.setPopulation(Integer.parseInt(stats[2]));
                }
            }
            if(stats[3] != null) {
                if(Integer.parseInt(stats[3]) >=0) {
                    crime.setMurder(Integer.parseInt(stats[3]));
                }
            }
            
            if(stats[4] != null) {
                if(Integer.parseInt(stats[4]) >=0) {
                    crime.setRobbery(Integer.parseInt(stats[4]));
                }
            }
            
            if(stats[5] != null) {
                if(Integer.parseInt(stats[5]) >=0) {
                    crime.setAssault(Integer.parseInt(stats[5]));
                }
            }
                
            if(stats[6] != null) {
                if(Integer.parseInt(stats[6]) >=0) {
                    crime.setBurglary(Integer.parseInt(stats[6]));
                }
            }
            
            if(stats[7] != null) {
                if(Integer.parseInt(stats[7]) >=0) {
                    crime.setLarceny(Integer.parseInt(stats[7]));
                }
            }
            
            if(stats[8] != null) {
                if(Integer.parseInt(stats[8]) >=0) {
                    crime.setMotorTheft(Integer.parseInt(stats[8]));
                }
            }
            
        }
            crimes.add(crime);
            System.out.println(crime);

            crimeInfo = bufferedReader.readLine();

        } while (crimeInfo != null);

        fileReader.close();
        bufferedReader.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (NumberFormatException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
}

These are methods I have so far.

    public static void carThefts() {
    Collections.sort(crimes, new Comparator<CityCrime>(){
        public int compare(CityCrime d1, CityCrime d2){
            return Integer.compare(d1.getMotorTheft(), d2.getMotorTheft());
        }
        
    });
}

public static void displayStateCarThefts() {
    int carTheft = 0;
    for(CityCrime crime : crimes) {
        if(crime.getState().equalsIgnoreCase(crime.getState())) {
            carTheft = carTheft + crime.getMotorTheft();
        }
        
        System.out.printf("%-20s %5s %10s\n", "State", ":" , crime.getState());
        System.out.printf("%-20s %5s %10d\n", "Motor Theft", ":" , carTheft);
    }

    

In my CityCrime.java I have

    public class CityCrime {


//Instance variables

private String city;
private String state;
private int population;
private int murder;
private int robbery;
private int assault;
private int burglary;
private int larceny;
private int motorTheft;
public int totalCrimes;


public static void main(String[] args) {
    
}

public int getTotalCrimes() {
    return totalCrimes;
}

public int setTotalCrimes(int murder, int robbery, int assault, int burglary, int larceny, int motorTheft) {
    this.totalCrimes = murder + robbery + assault + burglary + larceny + motorTheft;
    return totalCrimes;
}

public String getCity() {
    return city;
}


public void setCity(String city) {
    this.city = city;
}

public String getState() {
    return state;
}


public void setState(String state) {
    if(state.equalsIgnoreCase("ALABAMA")) {
        this.state = "AL";
    }
    else if(state.equalsIgnoreCase("ALASKA")) {
        this.state = "AK";
    }

    //etc

public int getMurder() {
    return murder;
}


public void setMurder(int murder) {
    this.murder = murder;
}


public int getRobbery() {
    return robbery;
}


public void setRobbery(int robbery) {
    this.robbery = robbery;

}


public int getAssault() {
    return assault;
}


public void setAssault(int assault) {
    this.assault = assault;

}


public int getBurglary() {
    return burglary;
}


public void setBurglary(int burglary) {
    this.burglary = burglary;

}


public int getLarceny() {
    return larceny;
}


public void setLarceny(int larceny) {
    this.larceny = larceny;
}


public int getMotorTheft() {
    return motorTheft;
}


public void setMotorTheft(int motorTheft) {
    this.motorTheft = motorTheft;

}

public static void showAllMurderDetails() {

    for (CityCrime crime : StartApp.crimes) {
        System.out.println("Crime: City= " + crime.getCity() + ", Murder= " + crime.getMurder());
    }
    System.out.println();
}


public static int showAllViolentCrimes() {
    int total = 0;
    for(CityCrime crime : StartApp.crimes) {
        total=total+crime.getMurder();
        total=total+crime.getRobbery();
        total=total+crime.getAssault();
    }
    System.out.println("Total of violent crimes: " + total);
    return total;
    
}

public static int getPossessionCrimes() {
    int total=0;
    for (CityCrime crime : StartApp.crimes) {
        total = total + crime.getBurglary();
        total = total + crime.getLarceny();
        total = total + crime.getMotorTheft();
    }
    System.out.println("Total of possession crimes: " + total);
    return total;
}

}

I have also went down this route but find myself stuck still :

        public static void displayStateCarThefts() {
    Map<String, CityCrime> map = new HashMap<>();
    for(CityCrime c : crimes) {
        
        CityCrime crime = map.get(c.getState());
        if(crime != null) {
            crime.setMotorTheft(crime.getMotorTheft()+c.getMotorTheft());
        }
        else {
            map.put(c.getState(), c);
        }
    }
    System.out.println(map.values());
    //System.out.println(Arrays.asList(map.values().toArray()));    

}

Really appreciate any help with this. Thankyou

4
  • Your collegue already asked the same identical question... look at stackoverflow.com/questions/68754139/… Commented Aug 12, 2021 at 13:44
  • @Davide, please check the expected output, they are different questions. This question is to go through the arraylist and for all states of the same name, to add their motorTheft value Commented Aug 12, 2021 at 16:26
  • If I understand well, you have a List of CityCrime, each CityCrime is linked at a State, with a number of car thefts, and you want to get a Map where the key is the State and the value, the number of car thefts in cities of this states? I'm not sure about that, because in your last function, your Map has for value type CityCrime and not Integer Commented Aug 13, 2021 at 10:52
  • @Oromis, yes that's correct. Please ignore my last function as it is wrong, I was just showing what things I'm currently trying. I want to add all motor thefts together of the same state Commented Aug 13, 2021 at 12:03

1 Answer 1

1

Here my solution:

public static void displayStateCarThefts() {
        final var map = new HashMap<String, Integer>();
        for(var c : crimes) {
            final int previousValue = map.getOrDefault(c.getState(), 0); // If the key does not exist, return 0 as default value
            map.put(c.getState(), previousValue + c.getMotorTheft()); // Update the value on the Map
        }

        final var sortedKeys = new LinkedList<>(map.keySet()); // Create a new list of String with all keys inside
        sortedKeys.sort(Comparator.naturalOrder()); // Sort keys in natural order
        for(final var key: sortedKeys) // Iterate over keys
            System.out.println(key + " " + map.get(key));

}

I see you use ArrayList, I recommand you to use instead LinkedList. ArrayList is an implementation of List using Java array. It is really good to access to a specific element (nth element) but this type of list is not optimal otherwise. Indeed, the implementation have to create new array internally if you want to add an element and if this internal array is full.
LinkedList use the the principle of chained list. Each object inside is wrap in a Node, and Node is connected to previous and next Node forming the list. This type of List is not really efficient to access to nth element, but there is no extra cost to add an element (by add function).
From an iteration perspective, both are, I think, similar in performance.

Why not sort directly the Map?

Because Map is an orderless type. So if there is no order, we can't sort the map.
Don't hesitate if you have any other questions about the code!

Sign up to request clarification or add additional context in comments.

1 Comment

thankyou! I has tried using map but couldn't wrap my head around it, your code and comments definitely helped so thankyou very much I appreciate it. If by chance you are enjoying teaching / answering these types of questions, I have another question on my page :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.