-1

I have to take input from the user in CSV format (area,city,state, pincode). I have created Map<String, Map<String, Integer>>. Output should have State name in the first line and each city name along with the count of address in the city in the next lines. A sample of input and output is like in the added image.

Input and Output Sample Picture

1

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
    public static void main(String args[]) throws IOException {
        Map<String, Map<String, Integer>> address1 = new LinkedHashMap<String, Map<String, Integer>>();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Enter the number of address:");
        int n = Integer.parseInt(br.readLine());
        for(int i = 1; i <= n; i++) {
            Map<String, Integer> address2 = new LinkedHashMap<String, Integer>();
            System.out.println("Enter the address:");
            String input[] = br.readLine().split(",");
            if(address2.containsKey(input[1])) {
                address2.replace(input[1], (address2.get(input[1]) + 1));
            }
            else {
                address2.put(input[1], 1);
            }
            address1.put(input[2], address2);
        }
        br.close();
        System.out.println("Number of entries in city/state wise:");
        ArrayList<Object> data = new ArrayList<Object>(address1.keySet());
        ArrayList<Object> data2 = new ArrayList<Object>(address1.values());
        for(int i = 0; i < address1.size(); i++) {
            Object obj = data.get(i);
            System.out.println("State:" + obj + "\n");
            for(int j = 0; j < data2.size(); j++) {
                Object obj2 = data2.get(j);
                System.out.print("City:" + obj2 + "\n");
            }
        }
    }
}
cyberbrain
  • 3,433
  • 1
  • 12
  • 22
Gudu
  • 3
  • 1
  • 1
    Add all information as text not as image – Jens Jan 12 '23 at 16:34
  • 1
    I would probably create POJOs for the information before processing it. That way it's more extensible and easier to maintain – g00se Jan 12 '23 at 17:41
  • [*How do I ask and answer homework questions?*](https://meta.stackoverflow.com/q/334822/642706) – Basil Bourque Jan 15 '23 at 09:19
  • You can make your own code more readable, if you choose different names for your map: `address1` and `address2` would better be named something in the pattern of *valueByKey*, e.g. `countByCity` instead of `address2`. Also `data` and `data2` are not very helpful for us (and *you* ) to understand the existing code. Regarding the `n`... usually one-letter variable names are only (if at all) good for loop counters. – cyberbrain Jan 15 '23 at 11:01

1 Answers1

0

For the sake of simplicity, the below code assumes that all input, entered by the user, is valid.

Consider using class Scanner for getting input from the user.
(More explanations after the below code.)

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        try (Scanner stdin = new Scanner(System.in)) {
            int n = stdin.nextInt();
            stdin.nextLine();
            Map<String, Map<String, Integer>> states = new HashMap<>();
            int count;
            for (int i = 0; i < n; i++) {
                System.out.print("Enter address: ");
                String line = stdin.nextLine();
                String[] fields = line.split(",");
                Map<String, Integer> cities = states.get(fields[2]);
                if (cities == null) {
                    cities = new HashMap<>();
                    states.put(fields[2], cities);
                }
                if (cities.containsKey(fields[1])) {
                    count = cities.get(fields[1]);
                }
                else {
                    count = 0;
                }
                cities.put(fields[1], count + 1);
            }
            for (String state : states.keySet()) {
                System.out.println("State: " + state);
                Map<String, Integer> citys = states.get(state);
                for (String city : citys.keySet()) {
                    System.out.printf("City: %s Count: %d%n", city, citys.get(city));
                }
            }
        }
    }
}

In the code in your question, you are creating a new address2 map for each line entered by the user. When you create a new Map, it is empty, i.e. it has no entries. You want to create a new address2 map only if there is no entry for the state in the address entered by the user, otherwise you want the existing address2 map. If address1 map does not contain an entry for the state, then method get returns null. Similarly for address2 map: if it does not contain an entry for the city, its get method will also return null.

Also refer to Scanner is skipping nextLine() after using next() or nextFoo()? regarding using class Scanner.

Here is a sample run of the above code:

3
Enter address: Avocado Ave,Newport Beach,california,92660
Enter address: Beachwalk,Honolulu,Hawaii,96815
Enter address: Hana Highway,Maui,Hawaii,96815
State: Hawaii
City: Honolulu Count: 1
City: Maui Count: 1
State: california
City: Newport Beach Count: 1
Abra
  • 19,142
  • 7
  • 29
  • 41