【问题标题】:Formatting Output to CSV File Format to Account for Empty Values In Some Rows将输出格式化为 CSV 文件格式以考虑某些行中的空值
【发布时间】:2015-10-12 18:56:00
【问题描述】:

tl;dr:我想以我正在阅读的相同 CSV 文件格式输出我的 HashMap

我想以此作为开头:我可能会以错误的方式处理这件事。因为我开始思考一件事,并没有考虑到我遇到的这个问题。因此,我正在尝试制作一个小型应用程序,它会根据您喜欢的类型为您提供随机电影供您观看(类似于 Netflix 的 Max 应用程序,但相当笨拙)。我有一个电影列表,我将自己格式化为 CSV 格式,因为我最近编写了一些从 CSV 文件中读取值的代码,并且我没有太多可更改的地方。

这是两难境地:我已经阅读了 CSV 格式的文件(只有两行示例文件),因为我知道哪些列包含我使用 BufferedReader 逐行读取存储分隔的每个值的内容ArrayList 中的值(我知道有更好的方法,但这是我现在想出的)然后我根据流派将每个 ArrayList 存储到 HashMap 中。现在我希望能够在某个时候写回同一个文件来编辑它。所以已经看过的电影将从HashMap中删除,然后覆盖文件,这样下次读回时,已经看过的电影就不会再在文件中了。所以我现在遇到的困难是格式化输出以考虑实际 CSV 中的空白。

例如,我的测试文件只包含两行,其中每个电影类型都有两部电影,除了戏剧和喜剧。所以文件看起来像这样

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

只是为了巩固我想要/期望的输出;假设我看科幻/奇幻2,这是一部好电影,但它得走了,我想要删除后的输出是这样的

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

但我知道我不会得到这些结果,因为当我简单地读取文件然后将其输出回来时,我会得到:

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

所以在得到这些结果后,我现在意识到我的计划不够好,并且想知道我是否走错了路。有谁知道如何按照我描述的方式格式化?我试图找到一个解决方案,但在空手而归之后,我推断出我想要的格式可能与 CSV 的外观不符,考虑到文件中的某些单元格必须为空白。我尝试保留文件中的任何空格,以便它们进入哈希映射,但结果是相同的。我考虑过完全绕过输出文件,但我不确定如何将我最初读取的值保存到我的地图中。任何想法或解决方案将不胜感激。这是完成所有工作的类:

 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]);
                }
            }
        }
        buffRdr.close();
        moviesFile = fileOfMovies;
    } catch (FileNotFoundException err) {
        err.printStackTrace();
        System.out.println("Error: Unable to locate file specified");
    }
}

public void mapMoviesToGenre(){
    moviesByGenre.put(GENRES[GENRE_1], actionMovies);
    moviesByGenre.put(GENRES[GENRE_2], dramaMovies);
    moviesByGenre.put(GENRES[GENRE_3], sciFiFantasyMovies);
    moviesByGenre.put(GENRES[GENRE_4], thrillerSuspenseMovies);
    moviesByGenre.put(GENRES[GENRE_5], comedyMovies);

}

public void initMapToOutput() {

    mapMoviesToGenre();
    FileWriter fileWriter = null;
    try {
        fileWriter = new FileWriter(moviesFile);
        fileWriter.append(NEW_LINE);

        for(ArrayList<String> moviesInGenre : moviesByGenre.values()){
            for(String movie : moviesInGenre){
                fileWriter.append(movie);
                fileWriter.append(DELIMITER);
            }
            fileWriter.append(NEW_LINE);
        }

    } catch (Exception err) {
        err.printStackTrace();

    } finally {
        try {
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException err) {
            err.printStackTrace();
        }
    }

}

}

我不认为它的格式很好,但我对此有些无知,任何人都可以随意编辑。我已经意识到必须有更好的方法来存储从文件中读取的值,但现在我专注于解决另一个难题。但是,如果有人愿意指出其他任何内容,请随意。

【问题讨论】:

  • 有很多东西可以阅读。 ;)
  • 所以在查看了我的帖子后,我意识到也许我应该将值存储在 CSV 中,然后再读取为行值而不是列值,因为输出已经这样做了。当我使用不需要的输出再次运行程序时,它会将其格式化回原来的格式。这告诉我,无论是我阅读还是输出的方式都必须给予。我暂时不会处理这个问题,谁能确认这实际上是我的问题?
  • @Satya 是的......对不起,我尽量做到描述性。我的红牛放大了我的描述性。很抱歉¯_(ツ)_/¯

标签: java csv file-io hashmap bufferedreader


【解决方案1】:

好的,所以我处理了它,它可能与谁有关。我继续将电影逐行分组,而不是逐列分组。我所要做的就是将我的代码的while 部分更改为此

 int index = 0;
        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 ((index == GENRE_1) && !lnPtr[i].isEmpty()) {
                    actionMovies.add(lnPtr[i]);
                } else if ((index == GENRE_2) && !lnPtr[i].isEmpty()) {
                    dramaMovies.add(lnPtr[i]);
                } else if ((index == GENRE_3) && !lnPtr[i].isEmpty()) {
                    sciFiFantasyMovies.add(lnPtr[i]);
                } else if ((index == GENRE_4) && !lnPtr[i].isEmpty()) {
                    thrillerSuspenseMovies.add(lnPtr[i]);
                } else if ((index == GENRE_5) && !lnPtr[i].isEmpty()){
                    comedyMovies.add(lnPtr[i]);
                }
            }
            index++;
        }

我现在每次都在同一条线上获得相同类型的电影,尽管有时顺序不同,我认为这是由于进出HashMap。如果有人知道更清洁更有效的方法,请随时分享,但我现在解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    相关资源
    最近更新 更多