0

I am practising java which is new for me and learned recently about collections in java. I want to parse a csv file and store it on a hashmap. Also , I don't want to use any parser.

My CSV file:-

id,date,ministry,questions
2011,15.02.2014,HEALTH,What was the outcome
20757,24.02.2015,"DEFENCE , FINANCE" ,"Your budget this year .."
20113,17.03.2013,HEALTH, Hospitals build

So , I have few questions:-

  • I want to have "DEFENCE , FINANCE" in same column. How will I use regex to remove "," so that , separator doesn't set new column
  • I want to display number of question asked in each ministry department. Here ex:- HEALTH have total 2 questions etc.
  • Also no duplicates.

I am parsing through I/O filereader.

My code:-

public class MainData {

    public static void main(String[] args) throws IOException ,FileNotFoundException{

        String line = "";
        String cvsSplitBy = ",";

    try{
        BufferedReader br = new BufferedReader(new FileReader("src/main/resources/rj.csv"));
        HashMap<String,String> rjFile = new HashMap<String, String>();
        System.out.println("running"+rjFile);


        while ((line = br.readLine()) != null) {

            String[] rj = line.split(cvsSplitBy);

            System.out.println(br);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

PS:- I wan to use only map related collections.

NoobCoder
  • 493
  • 8
  • 25
  • Regarding your first point use this regex: `line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");` See [Splitting on comma outside quotes](https://stackoverflow.com/questions/18893390/splitting-on-comma-outside-quotes) for explanation. Regarding your second point: Either use a `Map>` where you store ministry as key and the questions in a list or if you are only interested in the count use `Map` where you store ministry as key and increment the question count while parsing your file. – Eritrean Oct 24 '19 at 10:48
  • @Eritrean Hi, for second part , I am likely to have second part of your explanation but I have less idea to implement. Can you show how I can do this is my code ? – NoobCoder Oct 24 '19 at 12:33
  • I've added a simple example to get you started. – Eritrean Oct 24 '19 at 13:56

1 Answers1

1

Here is a simple example to get you started. I've put both approaches (list of questions & questions count). Choose one that suits your need and delete the other or use both:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainData {
    public static void main(String[] args) throws IOException, FileNotFoundException {
        String line = "";
        String cvsSplitBy = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)";

        try {
            BufferedReader br = new BufferedReader(new FileReader("src/main/resources/rj.csv"));
            Map<String, List<String>> questListByMinistry = new HashMap<>();
            Map<String, Integer> questCountByMinistry = new HashMap<>();
            //skip the first line (header)
            br.readLine();
            while ((line = br.readLine()) != null) {
                String[] rj = line.split(cvsSplitBy);

                if(!questCountByMinistry.containsKey(rj[2])){
                    //if the ministry doesn't exist as key yet put it to your map and put the value 1
                    questCountByMinistry.put(rj[2], 1);
                }
                else{
                    //else if it already exist get the current value and add +1
                    questCountByMinistry.put( rj[2], questCountByMinistry.get(rj[2])+1);
                }

                //-----------------------------------------------

                if(!questListByMinistry.containsKey(rj[2])){
                    //if key doesen't exist put it to map and create a new list                    
                    questListByMinistry.put(rj[2], new ArrayList<>());
                    // and add the question to the list
                    questListByMinistry.get(rj[2]).add(rj[3]);
                }
                else{
                    //else if key already exists get the list associated to key and add the question
                    questListByMinistry.get(rj[2]).add(rj[3]);
                }                
            }
            System.out.println(questCountByMinistry);
            System.out.println(questListByMinistry);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

If you are using Java8 or above/ If you want to make yourself familliar with the feutures of Java8

the above code could be rewriten to:

public static void main(String[] args) throws IOException, FileNotFoundException {
    String line = "";
    String cvsSplitBy = ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)";

    try {
        BufferedReader br = new BufferedReader(new FileReader("src/main/resources/rj.csv"));
        Map<String, List<String>> questListByMinistry = new HashMap<>();
        Map<String, Integer> questCountByMinistry = new HashMap<>();
        //skip the first line 
        br.readLine();
        while ((line = br.readLine()) != null) {
            String[] rj = line.split(cvsSplitBy);
            questListByMinistry.computeIfAbsent(rj[2], k -> new ArrayList<>()).add(rj[3]);
            questCountByMinistry.compute(rj[2], (k,v) -> v==null? 1 : v+1);                    
        }
        System.out.println(questCountByMinistry);
        System.out.println(questListByMinistry);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Eritrean
  • 15,851
  • 3
  • 22
  • 28
  • Thanks , Learned something new . Also how can I write test cases for file handling exception and loading data using JUnit – NoobCoder Oct 24 '19 at 18:18