Modify Specified Value(s) in a CSV File and Write Them Back

Question

I want to output my HashMap in the same CSV file format that I am reading it in.

I want to preface this with: I may be going about this the wrong way. Because I started this thinking one thing and didn’t account for this problem I’m having. So I’m trying to make a small application that will give you a random movie to watch depending on what genre you are in the mood for (similarly to Netflix’s Max application, but considerably dumbed down). I have a list of movies that I’m going to format myself in CSV format, because I recently wrote some code that reads in values from a CSV file and I didn’t have much to alter.

Here is the dilemma: I have read in the CSV-formatted file (only a two line sample file), since I know what columns contain what I use a BufferedReader to read in line by line storing each value of the delimited value in its own ArrayList (I know there is a better way but this is what I came up with for now) I then store each ArrayList according to genre into a HashMap. Now I want to be able to write back out to the same file at some point to edit it. So movies that have been watched will be removed from the HashMap and then overwrite the file, so that when it’s read back in next time the movie that was already watched will not be in the file anymore. So the difficulty I am having at this point is formatting the output back out to account for empty spaces in the actual CSV.

So for example, the test file I have only contains two lines where each movie genre has two movies except for drama and comedy. So the file looks like this:

 

Action,Drama,Sci-fi/Fantasy,Thriller/Suspense,Comedy Action2,,Sci-fi/Fantasy2,Thriller/Suspense2,

 

Just to solidify what output I want/expected; Say I watch Sci-fi/Fantasy2, it was a good movie, but it's gotta go, the output I want once removed is this

 

Action,Drama,Sci-fi/Fantasy,Thriller/Suspense,Comedy Action2,,,Thriller/Suspense2,

 

But I know I'm not going to get those results because when I simply read the file then output it back out I get:

 

Action,Action2, Drama,, Thriller/Suspense,Thriller/Suspense2, Comedy,, Sci-fi/Fantasy,Sci-fi/Fantasy2,

 

So after getting these results I now realize I didn't plan well enough, and wonder if I'm going about this the wrong way. Does anyone know how to format in the way I described? I tried to find a solution, but after coming up empty-handed I deduced that maybe the format I want goes against how a CSV should look, considering some cells in the file would have to be blank. I tried keeping all blank spaces from the file so they would go into the HashMap, but results were the same. I thought about bypassing the output file altogether, but I'm not sure how to save the values I originally read in that go into my map. Any ideas or solutions would be greatly appreciated. Here is the class that does all the work:

 

package rngesus;

 

 import java.io.BufferedReader;

 import java.io.File;

 import java.io.FileNotFoundException;

 import java.io.FileReader;

 import java.io.FileWriter;

 import java.io.IOException;

 import java.util.ArrayList;

 import java.util.HashMap;

 

 public class ReadWrite {

 

private static final String[] GENRES = { "Action", "Drama",

        "Sci-Fi/Fantasy", "Thriller/Suspense", "Comedy" };

private static final String NEW_LINE = "\n";

private static final String DELIMITER = ",";

private static final int NUM_OF_COL = 5;

private static final int GENRE_1 = 0;

private static final int GENRE_2 = 1;

private static final int GENRE_3 = 2;

private static final int GENRE_4 = 3;

private static final int GENRE_5 = 4;

 

private static String moviesFile;

private HashMap<String, ArrayList<String>> moviesByGenre;

 

ArrayList<String> actionMovies;

ArrayList<String> dramaMovies;

ArrayList<String> sciFiFantasyMovies;

ArrayList<String> thrillerSuspenseMovies;

ArrayList<String> comedyMovies;

 

public ReadWrite() {

    moviesFile = "";

    moviesByGenre = new HashMap<String, ArrayList<String>>();

    actionMovies = new ArrayList<String>();

    dramaMovies = new ArrayList<String>();

    sciFiFantasyMovies = new ArrayList<String>();

    thrillerSuspenseMovies = new ArrayList<String>();

    comedyMovies = new ArrayList<String>();

}

 

public void readAndSortInputFile(String fileOfMovies) throws IOException {

 

    try {

        BufferedReader buffRdr = new BufferedReader(new FileReader(

                new File(fileOfMovies)));

        String line = "";

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

            String[] lnPtr = line.split(",", NUM_OF_COL);

            int diff = Math.min(lnPtr.length, NUM_OF_COL);

            for (int i = 0; i < diff; i++) {

                if ((i == GENRE_1) && !lnPtr[i].isEmpty()) {

                    actionMovies.add(lnPtr[i]);

                } else if ((i == GENRE_2) && !lnPtr[i].isEmpty()) {

                    dramaMovies.add(lnPtr[i]);

                } else if ((i == GENRE_3) && !lnPtr[i].isEmpty()) {

                    sciFiFantasyMovies.add(lnPtr[i]);

                } else if ((i == GENRE_4) && !lnPtr[i].isEmpty()) {

                    thrillerSuspenseMovies.add(lnPtr[i]);

                } else if ((i == GENRE_5) && !lnPtr[i].isEmpty()){

                    comedyMovies.add(lnPtr[i]);

                }

            }

 

Answer

It looks like your problem is modifying specified rows and columns in a CSV file. Actually, it’s not a problem by itself. The problem is that the Java code is rather complex. SPL (Structured Process Language) makes it easy to achieve the computing target:

A

1

=file("d:\\source.csv").import@c()

2

=A1.modify(2,null:#3)

3

=file("d:\\source.csv").export@c(A1)

A1: Import source.csv;

undefined

A2: Change value of field 3 in row 2 into null;

undefined

A3: Write modified A1 back to source.csv.

An SPL script can be easily integrated into a Java application. See How to Call an SPL Script in Java to know more about the integration.